首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >React / JSX动态组件名称

React / JSX动态组件名称
EN

Stack Overflow用户
提问于 2015-04-26 17:24:00
回答 14查看 184.7K关注 0票数 237

我正在尝试根据组件的类型动态呈现组件。

例如:

代码语言:javascript
运行
复制
var type = "Example";
var ComponentName = type + "Component";
return <ComponentName />; 
// Returns <examplecomponent />  instead of <ExampleComponent />

我尝试了这里提出的解决方案React/JSX dynamic component names

这在编译时给了我一个错误(使用browserify进行gulp)。在我使用数组语法的地方,它需要XML。

我可以通过为每个组件创建一个方法来解决这个问题:

代码语言:javascript
运行
复制
newExampleComponent() {
    return <ExampleComponent />;
}

newComponent(type) {
    return this["new" + type + "Component"]();
}

但这意味着我创建的每个组件都有一个新的方法。对于这个问题,一定有更好的解决方案。

我非常乐于接受建议。

EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2015-04-26 18:07:11

<MyComponent />编译为React.createElement(MyComponent, {}),它需要一个字符串(HTML )或一个函数(ReactClass)作为第一个参数。

您可以将组件类存储在一个名称以大写字母开头的变量中。参见HTML tags vs React Components

代码语言:javascript
运行
复制
var MyComponent = Components[type + "Component"];
return <MyComponent />;

编译为

代码语言:javascript
运行
复制
var MyComponent = Components[type + "Component"];
return React.createElement(MyComponent, {});
票数 228
EN

Stack Overflow用户

发布于 2016-12-01 03:01:42

这里有一个关于如何处理这种情况的官方文档:https://facebook.github.io/react/docs/jsx-in-depth.html#choosing-the-type-at-runtime

基本上它是这样说的:

错误:

代码语言:javascript
运行
复制
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} />;
}

正确:

代码语言:javascript
运行
复制
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} />;
}
票数 195
EN

Stack Overflow用户

发布于 2019-04-21 15:08:50

应该有一个容器将组件名称映射到所有应该动态使用的组件。组件类应该在容器中注册,因为在模块化环境中,没有其他地方可以访问它们。如果不显式指定组件类,就不能通过它们的名称来标识组件类,因为在生产中,函数name是最小化的。

组件映射

它可以是普通对象:

代码语言:javascript
运行
复制
class Foo extends React.Component { ... }
...
const componentsMap = { Foo, Bar };
...
const componentName = 'Fo' + 'o';
const DynamicComponent = componentsMap[componentName];
<DynamicComponent/>;

Map实例:

代码语言:javascript
运行
复制
const componentsMap = new Map([[Foo, Foo], [Bar, Bar]]);
...
const DynamicComponent = componentsMap.get(componentName);

普通对象更适合,因为它得益于属性速记。

Barrel模块

具有命名导出的barrel module可以充当这样的映射:

代码语言:javascript
运行
复制
// 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/>;

这在每个模块的代码样式中只有一个类的情况下工作良好。

装饰者

装饰器可以与类组件一起用于语法糖,这仍然需要显式地指定类名并在映射中注册它们:

代码语言:javascript
运行
复制
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'
  ...
}

装饰器可以用作具有功能组件的高阶组件:

代码语言:javascript
运行
复制
const Bar = props => ...;
Bar.displayName = 'Bar';

export default dynamic(Bar);

使用non-standard displayName而不是随机属性也有利于调试。

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29875869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档