动态组件名称 - React

时间:2018-03-16 17:11:05

标签: javascript reactjs

我有三个组成部分:

const Comp0 = () => <div>1</div>;
const Comp1 = () => <div>2</div>;
const Comp2 = () => <div>3</div>;

我还有一个班级,状态:

state = { activeComponent: 0 }

用户可以将此activeComponent更改为120

在渲染中,我有:

return (
   {React.createElement(`Comp${this.state.activeComponent}`)};
}

理论上应该有效。然而 - 我得到一个非常奇怪的错误。两个错误。

  1. Warning: <Comp0 /> is using uppercase HTML. Always use lowercase HTML tags in React.

  2. Warning: The tag <Comp0> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

  3. 它们如何同时出现?

3 个答案:

答案 0 :(得分:3)

您可以简单地渲染动态标记,如

const Tag = `Comp${this.state.activeComponent}`;
return (
   <Tag />
}

根据 docs

  

您不能将通用表达式用作React元素类型。如果你   我想使用一般表达式来表示类型   element,只需先将其分配给capitalized变量。

在你的情况下,它不起作用,因为你将字符串名称传递给React.createElement,而对于React组件,你需要传递组件,如

React.createElement(Comp0);

对于普通的DOM元素,您可以传递一个像

这样的字符串
React.createElement('div');

,因为你写了

`Comp${this.state.activeComponent}`

你得到的是

React.createElement('Comp0')

反应并不容易理解,它会发出警告

  

警告:<Comp0 />正在使用大写HTML。始终使用小写HTML   React中的标签。

答案 1 :(得分:1)

你可以使用这样的映射来执行一个函数:

const stateArray = [Comp0, Comp1, Comp2];
const getComp = (Comp) => <Comp>
const getCompFromArray = (i) => getComp(stateArray[i]);

答案 2 :(得分:1)

如果要使用React.createElement创建自定义组件元素,则必须将直接类/函数(而不是其名称(仅适用于DOM元素))传递给它,例如: React.createElement(Shoot0)代替React.createElement('Shoot0');

您可以通过将您想要的组件放入数组并将其编入索引来解决问题

&#13;
&#13;
const Shoot0 = () => <div>1</div>;
const Shoot1 = () => <div>2</div>;
const Shoot2 = () => <div>3</div>;

const Shoots = [Shoot0, Shoot1, Shoot2];

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      activeComponent: 0
    };
  }
  
  componentDidMount() {
    setInterval(() => {
      this.setState((prevState) => {
        return {
          activeComponent: (prevState.activeComponent + 1) % 3
        }
      })
    }, 1000)
  }
  
  render() {
    return React.createElement(Shoots[this.state.activeComponent])
  }
}

ReactDOM.render(<App />, document.getElementById('app'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;