首页 文章

React / JSX动态组件名称

提问于
浏览
100

我试图根据其类型动态呈现组件 .

例如:

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

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

这在编译时给了我一个错误(使用browserify for gulp) . 它期望我使用数组语法的XML .

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

newExampleComponent() {
    return <ExampleComponent />;
}

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

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

我对建议很开放 .

8 回答

  • -1

    <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, {});
    
  • 10

    这里有一个关于如何处理这种情况的官方文档: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} />;
    }
    
  • 0

    我想出了一个新的解决方案 . 请注意我使用的是ES6模块,所以我要求上课 . 您也可以定义一个新的React类 .

    var components = {
        example: React.createFactory( require('./ExampleComponent') )
    };
    
    var type = "example";
    
    newComponent() {
        return components[type]({ attribute: "value" });
    }
    
  • 86

    如果您的组件是全局的,您可以简单地执行:

    var nameOfComponent = "SomeComponent";
    React.createElement(window[nameOfComponent], {});
    
  • 7

    对于包装器组件,一个简单的解决方案是直接使用 React.createElement (使用ES6) .

    import RaisedButton from 'mui/RaisedButton'
    import FlatButton from 'mui/FlatButton'
    import IconButton from 'mui/IconButton'
    
    class Button extends React.Component {
      render() {
        const { type, ...props } = this.props
    
        let button = null
        switch (type) {
          case 'flat': button = FlatButton
          break
          case 'icon': button = IconButton
          break
          default: button = RaisedButton
          break
        }
    
        return (
          React.createElement(button, { ...props, disableTouchRipple: true, disableFocusRipple: true })
        )
      }
    }
    
  • 0

    我使用了一些不同的方法,因为我们总是知道我们的实际组件,所以我想应用switch case . 在我的案例中,组件的总数没有大约7-8 .

    getSubComponent(name) {
        let customProps = {
           "prop1" :"",
           "prop2":"",
           "prop3":"",
           "prop4":""
        }
    
        switch (name) {
          case "Component1": return <Component1 {...this.props} {...customProps} />
          case "Component2": return <Component2 {...this.props} {...customProps} />
          case "component3": return <component3 {...this.props} {...customProps} />
    
        }
      }
    
  • 108

    我们希望通过动态组件加载来访问各种视图 . 下面的代码给出了一个如何通过使用从URL的搜索字符串解析的字符串来实现此目的的工作示例 .

    让我们假设我们想要使用这些url路径访问具有两个独特视图的页面'snozberrys':

    'http://localhost:3000/snozberrys?aComponent'
    

    'http://localhost:3000/snozberrys?bComponent'
    

    我们像这样定义视图的控制器:

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom'
    import {
      BrowserRouter as Router,
      Route
    } from 'react-router-dom'
    import AComponent from './AComponent.js';
    import CoBComponent sole from './BComponent.js';
    
    const views = {
      aComponent: <AComponent />,
      console: <BComponent />
    }
    
    const View = (props) => {
      let name = props.location.search.substr(1);
      let view = views[name];
      if(view == null) throw "View '" + name + "' is undefined";
      return view;
    }
    
    class ViewManager extends Component {
      render() {
        return (
          <Router>
            <div>
              <Route path='/' component={View}/>
            </div>
          </Router>
        );
      }
    }
    
    export default ViewManager
    
    ReactDOM.render(<ViewManager />, document.getElementById('root'));
    
  • 3

    编辑:其他答案更好,请参阅评论 .

    我这样解决了同样的问题:

    ...
    render : function () {
      var componentToRender = 'component1Name';
      var componentLookup = {
        component1Name : (<Component1 />),
        component2Name : (<Component2 />),
        ...
      };
      return (<div>
        {componentLookup[componentToRender]}
      </div>);
    }
    ...
    

相关问题