当前位置: 首页 > 知识库问答 >
问题:

反应 / JSX 动态组件名称

商骞仕
2023-03-14

我试图根据组件的类型动态地渲染它们。

例如:

var type = "Example";
var ComponentName = type + "Component";
return <ComponentName />; 
// Returns <examplecomponent />  instead of <ExampleComponent />

我尝试了这里提出的解决方案React/JSX动态组件名称

这在编译时给了我一个错误(使用browserify代替gulp)。它需要XML,而我使用的是数组语法。

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

newExampleComponent() {
    return <ExampleComponent />;
}

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

但这意味着我创建的每个组件都有一个新方法。必须有一个更优雅的解决方案来解决这个问题。

我对各种建议持非常开放的态度。

共有3个答案

魏晨
2023-03-14

应该有一个容器将组件名映射到所有应该动态使用的组件。组件类应该在一个容器中注册,因为在模块化环境中,没有单独的地方可以访问它们。由于函数< code>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/>;

对于每个模块一个类的代码风格来说,这很好。

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

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);

使用非标准的< code>displayName代替random属性也有利于调试。

夹谷苗宣
2023-03-14

这里有一个关于如何处理这种情况的官方留档: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} />;
}
钦良弼
2023-03-14

<代码>

您可以将组件类存储在一个名称以大写字母开头的变量中。请参阅HTML标记与反应组件。

var MyComponent = Components[type + "Component"];
return <MyComponent />;

编译为

var MyComponent = Components[type + "Component"];
return React.createElement(MyComponent, {});
 类似资料:
  • 问题内容: 我正在尝试根据组件的类型动态呈现组件。 例如: 那给我一个编译时的错误(使用browserify进行gulp)。我使用数组语法的地方应该是XML。 我可以通过为每个组件创建一个方法来解决此问题: 但这将意味着为我创建的每个组件提供一种新方法。必须对此问题有一个更优雅的解决方案。 我很乐意提出建议。 问题答案: 编译为,它期望将字符串(HTML标记)或函数(ReactClass)作为第一

  • 我正在寻找渲染基于字符串的组件。本质上,我希望找到相当于JavaScript动态函数名能力的JSX()。 所以,如果我有一个字符串,比如

  • 假设以下和所有组件/fus/fci/ssg只有一个带有站点道具的h1。我想了解为什么它是一个有效的react元素,但这些元素的渲染效果并不相同。一个有h1元素,另一个没有。其想法是不为不同站点创建带有切换的大型组件,每个站点将根据导航选择进行交换。我没有看到任何关于这方面的文件,除非我错过了。。。 导航

  • 我已经用ReactJS和ES6进行了几天的实验,并创建了两个组件,即

  • 问题内容: 我需要动态加载React组件。 我从用户获取要加载为字符串的组件名称。我正在使用 webpack 。 如何动态加载组件,而不要使用静态import语句。似乎不评估表达式。我想要实现的是这样的事情。 但这似乎不起作用。 问题答案: 基本上,它可以归结为预先创建您将需要的所有块。然后,您只需要一种动态引用它们的方法。这是我基于的解决方案: http://henleyedition.com/

  • 问题内容: 我尝试编写一个React组件。对于html标题标签(h1,h2,h3等),其中标题优先级根据我们在道具中定义的优先级动态变化。 这是我尝试做的。 预期输出: 这是行不通的。有什么可能的方法可以做到这一点? 问题答案: 无法就地执行此操作,只需将其放在变量中(首字母大写):