動的に使用されるはずのすべてのコンポーネントにコンポーネント名をマップするコンテナが必要です。コンポーネントクラスはコンテナに登録する必要があります。モジュール環境では、コンポーネントクラスにアクセスできる場所が1つもないためです。機能name
は本番環境で縮小されるため、コンポーネントクラスは、明示的に指定しないと名前で識別できません。
コンポーネントマップ
それは単純なオブジェクトにすることができます:
class Foo extends React.Component { ... }
...
const componentsMap = { Foo, Bar };
...
const componentName = 'Fo' + 'o';
const DynamicComponent = componentsMap[componentName];
<DynamicComponent/>;
またはMap
インスタンス:
const componentsMap = new Map([[Foo, Foo], [Bar, Bar]]);
...
const DynamicComponent = componentsMap.get(componentName);
プレーンオブジェクトは、プロパティの省略表現から恩恵を受けるため、より適しています。
バレルモジュール
名前付きエクスポートを備えたバレルモジュールは、そのようなマップとして機能できます。
// 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/>;
これは、モジュールのコードスタイルごとに1つのクラスでうまく機能します。
デコレータ
デコレータは、構文砂糖のクラスコンポーネントで使用できますが、これにはクラス名を明示的に指定してマップに登録する必要があります。
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'
...
}
デコレーターは、機能コンポーネントを持つ高次コンポーネントとして使用できます。
const Bar = props => ...;
Bar.displayName = 'Bar';
export default dynamic(Bar);
ランダムプロパティの代わりに非標準をdisplayName
使用すると、デバッグにも役立ちます。
{...this.props}
、親からサブタイプのコンポーネントに小道具を透過的に渡すのに役立つでしょう。いいねreturn <MyComponent {...this.props} />