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:
class Foo extends React.Component { ... }
...
const componentsMap = { Foo, Bar };
...
const componentName = 'Fo' + 'o';
const DynamicComponent = componentsMap[componentName];
<DynamicComponent/>;
Ou Map
exemplo:
const componentsMap = new Map([[Foo, Foo], [Bar, Bar]]);
...
const DynamicComponent = componentsMap.get(componentName);
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:
// Foo.js
export class Foo extends React.Component { ... }
// dynamic-components.js
export * from './Foo';
export * from './Bar';
// some module that uses dynamic component
import * as componentsMap from './dynamic-components';
const componentName = 'Fo' + 'o';
const DynamicComponent = componentsMap[componentName];
<DynamicComponent/>;
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:
const componentsMap = {};
function dynamic(Component) {
if (!Component.displayName)
throw new Error('no name');
componentsMap[Component.displayName] = Component;
return Component;
}
...
@dynamic
class Foo extends React.Component {
static displayName = 'Foo'
...
}
Um decorador pode ser usado como componente de ordem superior com componentes funcionais:
const Bar = props => ...;
Bar.displayName = 'Bar';
export default dynamic(Bar);
O uso de propriedades não padrão emdisplayName
vez de propriedades aleatórias também beneficia a depuração.
{...this.props}
útil transmitir de maneira transparente adereços para componentes subtipados do pai. Comoreturn <MyComponent {...this.props} />