Estou tentando renderizar componentes dinamicamente com base em seu tipo.
Por exemplo:
var type = "Example";
var ComponentName = type + "Component";
return <ComponentName />;
// Returns <examplecomponent /> instead of <ExampleComponent />
Eu tentei a solução proposta aqui Nomes de componentes dinâmicos React / JSX
Isso me deu um erro ao compilar (usando o browserify para gulp). Esperava XML onde eu estava usando uma sintaxe de matriz.
Eu poderia resolver isso criando um método para cada componente:
newExampleComponent() {
return <ExampleComponent />;
}
newComponent(type) {
return this["new" + type + "Component"]();
}
Mas isso significaria um novo método para cada componente que eu criar. Deve haver uma solução mais elegante para esse problema.
Estou muito aberto a sugestões.
{...this.props}
útil transmitir de maneira transparente adereços para componentes subtipados do pai. Comoreturn <MyComponent {...this.props} />
Há uma documentação oficial sobre como lidar com essas situações está disponível aqui: https://facebook.github.io/react/docs/jsx-in-depth.html#choosing-the-type-at-runtime
Basicamente diz:
Errado:
Corrigir:
fonte
Deve haver um contêiner que mapeie os nomes dos componentes para todos os componentes que devem ser usados dinamicamente. As classes de componentes devem ser registradas em um contêiner, pois no ambiente modular não há outro local onde elas possam ser acessadas. As classes de componentes não podem ser identificadas por seus nomes sem especificá-las explicitamente porque a função
name
é minificada na produção.Mapa de componentes
Pode ser um objeto simples:
Ou
Map
exemplo:O objeto simples é mais adequado porque se beneficia da abreviação de propriedades.
Módulo barril
Um módulo barril com exportações nomeadas pode atuar como esse mapa:
Isso funciona bem com uma classe por estilo de código do módulo.
Decorador
Os decoradores podem ser usados com componentes de classe para açúcar sintático, isso ainda requer especificar nomes de classes explicitamente e registrá-los em um mapa:
Um decorador pode ser usado como componente de ordem superior com componentes funcionais:
O uso de propriedades não padrão em
displayName
vez de propriedades aleatórias também beneficia a depuração.fonte
Eu descobri uma nova solução. Observe que estou usando os módulos ES6, por isso estou exigindo a classe. Você também pode definir uma nova classe React.
fonte
default
atributo? ie: require ('./ ExampleComponent'). default?Se seus componentes são globais, você pode simplesmente:
fonte
Components
matriz não está definida.Para um componente do wrapper, uma solução simples seria usar
React.createElement
diretamente (usando o ES6).fonte
Em todas as opções com mapas de componentes, não encontrei a maneira mais simples de definir o mapa usando a sintaxe curta do ES6:
fonte
Ter um mapa não parece nada bom com uma grande quantidade de componentes. Estou realmente surpreso que ninguém tenha sugerido algo assim:
Este realmente me ajudou quando eu precisava renderizar uma quantidade bastante grande de componentes carregados em uma forma de matriz json.
fonte
React.createElement(MyComponent)
diretamente gerou um erro. Especificamente, não quero que o pai precise conhecer todos os componentes a serem importados (em um mapeamento) - porque isso parece uma etapa extra. Em vez disso, eu useiconst MyComponent = require("path/to/component/" + "ComponentNameString").default; return <MyComponent />
.Suponha que desejamos acessar várias visualizações com o carregamento dinâmico de componentes. O código a seguir fornece um exemplo prático de como fazer isso usando uma cadeia de caracteres analisada a partir da cadeia de pesquisa de um URL.
Vamos supor que queremos acessar uma página 'snozberrys' com duas visualizações exclusivas usando estes caminhos de URL:
e
nós definimos o controlador da nossa view assim:
fonte
Suponha que temos um
flag
, não diferente dostate
ouprops
:Com a bandeira,
Compo
preencha com um deComponentOne
ouComponentTwo
e, em seguida, eleCompo
pode agir como um componente de reação.fonte
Eu usei uma abordagem um pouco diferente, como sempre sabemos nossos componentes reais, então pensei em aplicar o caso do switch. Também o número total de componentes estava em torno de 7-8 no meu caso.
fonte
Editar: Outras respostas são melhores, ver comentários.
Eu resolvi o mesmo problema desta maneira:
fonte
React.createElement
será invocado para cada componente em seu objeto de pesquisa, mesmo que apenas um deles esteja sendo renderizado por vez. Pior, ao colocar o objeto de pesquisa norender
método do componente pai, ele fará isso novamente sempre que o pai for renderizado. As principais respostas são uma maneira muito melhor de conseguir a mesma coisa.