Debe haber un contenedor que asigne los nombres de los componentes a todos los componentes que se supone que deben usarse dinámicamente. Las clases de componentes deben registrarse en un contenedor porque, en un entorno modular, no hay un lugar único donde se pueda acceder. Las clases de componentes no se pueden identificar por sus nombres sin especificarlas explícitamente porque la función name
se minimiza en la producción.
Mapa de componentes
Puede ser objeto simple:
class Foo extends React.Component { ... }
...
const componentsMap = { Foo, Bar };
...
const componentName = 'Fo' + 'o';
const DynamicComponent = componentsMap[componentName];
<DynamicComponent/>;
O Map
instancia:
const componentsMap = new Map([[Foo, Foo], [Bar, Bar]]);
...
const DynamicComponent = componentsMap.get(componentName);
El objeto simple es más adecuado porque se beneficia de la taquigrafía de la propiedad.
Módulo de barril
Un módulo de barril con exportaciones con nombre puede actuar como tal 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/>;
Esto funciona bien con una clase por estilo de código de módulo.
Decorador
Los decoradores se pueden usar con componentes de clase para azúcar sintáctico, esto aún requiere especificar los nombres de clase explícitamente y registrarlos en un 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'
...
}
Se puede usar un decorador como componente de orden superior con componentes funcionales:
const Bar = props => ...;
Bar.displayName = 'Bar';
export default dynamic(Bar);
El uso de propiedad no estándar endisplayName
lugar de aleatoria también beneficia la depuración.
{...this.props}
útil pasar de manera transparente los accesorios a los componentes subtipados del padre. Me gustareturn <MyComponent {...this.props} />