; // Returns
我正在尝试根据组件的类型动态呈现组件。
例如:
var type = "Example";
var ComponentName = type + "Component";
return <ComponentName />;
// Returns <examplecomponent /> instead of <ExampleComponent />
我尝试了这里提出的解决方案React/JSX dynamic component names
这在编译时给了我一个错误(使用browserify进行gulp)。在我使用数组语法的地方,它需要XML。
我可以通过为每个组件创建一个方法来解决这个问题:
newExampleComponent() {
return <ExampleComponent />;
}
newComponent(type) {
return this["new" + type + "Component"]();
}
但这意味着我创建的每个组件都有一个新的方法。对于这个问题,一定有更好的解决方案。
我非常乐于接受建议。
发布于 2015-04-26 10:07:11
<MyComponent />
编译为React.createElement(MyComponent, {})
,它需要一个字符串(HTML )或一个函数(ReactClass)作为第一个参数。
您可以将组件类存储在一个名称以大写字母开头的变量中。参见HTML tags vs React Components。
var MyComponent = Components[type + "Component"];
return <MyComponent />;
编译为
var MyComponent = Components[type + "Component"];
return React.createElement(MyComponent, {});
发布于 2016-11-30 19:01:42
这里有一个关于如何处理这种情况的官方文档:https://facebook.github.io/react/docs/jsx-in-depth.html#choosing-the-type-at-runtime
基本上它是这样说的:
错误:
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// Wrong! JSX type can't be an expression.
return <components[props.storyType] story={props.story} />;
}
正确:
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// Correct! JSX type can be a capitalized variable.
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
发布于 2019-04-21 07:08:50
应该有一个容器将组件名称映射到所有应该动态使用的组件。组件类应该在容器中注册,因为在模块化环境中,没有其他地方可以访问它们。如果不显式指定组件类,就不能通过它们的名称来标识组件类,因为在生产中,函数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);
普通对象更适合,因为它得益于属性速记。
Barrel模块
具有命名导出的barrel module可以充当这样的映射:
// 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/>;
这在每个模块的代码样式中只有一个类的情况下工作良好。
装饰者
装饰器可以与类组件一起用于语法糖,这仍然需要显式地指定类名并在映射中注册它们:
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);
使用non-standard displayName
而不是随机属性也有利于调试。
https://stackoverflow.com/questions/29875869
复制相似问题