在React中将组件名称注入到标记中

时间:2017-10-03 15:52:32

标签: javascript reactjs react-redux

以前曾经问过,但解决方案似乎对我不起作用...也许是因为我有条件渲染?我的想法是我可以选择让用户点击,然后在onClick上呈现相应的组件。所以我想在用户做出选择时有条件地将组件的名称注入到标签中。这是一个相当小的例子:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import RaisedButton from 'material-ui/RaisedButton';
import { setData } from '../../actions/data';
import * as mathUtils from '../../mathUtils';

class MyParentClass extends Component {
  constructor(props) {
    super(props);
    this.handleChoice = this.handleChoice.bind(this);
  }
  handleChoice({ topic, user }) {
    const id = `${Date.now()}-${mathUtils.uuidv4()}`;
    this.props.setData({ topic, id, user });
  }
  render() {
    const { id, currentUser } = this.props;
    const Topic = this.props.topic;
    return (
      id
        ? <Topic />
        : <RaisedButton
            role="button"
            primary={true}
            label="NumberOne"
            onClick={() => this.handleChoice({
                topic: 'NumberOne',
                user: currentUser
              })
            }
          />
          <br />
          <RaisedButton
            role="button"
            primary={true}
            label="NumberTwo"
            onClick={() => this.handleChoice({
                topic: 'NumberTwo',
                user: currentUser
              })
            }
          />
    );
  }
}

MyParentClass.propTypes = {
  id: PropTypes.string,
  topic: PropTypes.string,
  setData: PropTypes.func.isRequired,
  currentUser: PropTypes.object.isRequired
};

MyParentClass.defaultProps = {
  id: null,
  topic: null
};

export default connect(
  ({ session, data }) => ({
    currentUser: session.currentUser,
    id: data.id,
    topic: data.topic
  }),
  { setData }
)(MyParentClass);

我在控制台中遇到两个不同的错误,这些错误似乎彼此不一致。第一个是Warning: <NumberOne /> is using uppercase HTML. Always use lowercase HTML tags in React.,第二个是Warning: The tag <NumberOne> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

我有理由相信我只是没有将正确的逻辑应用到我的应用程序中,但我不确定如何实现所需的行为。

2 个答案:

答案 0 :(得分:2)

您可以直接设置element而不是string。首先import您的组件

import NumberOne from '../../NumberOne';

然后,在onClick中设置相应的组件,如

onClick={() => this.handleChoice({
            topic: NumberOne,
            user: currentUser
          })

代码的其余部分与上述更改一样适合您。

答案 1 :(得分:0)

我相信在你的情况下topic应该是一个jsx函数,而不是一个字符串。

例如,伪代码:

// Outer render
render() {
    const topicOne = (props) => (<div>Topic One</div>);
    const topicTwo = (props) => (<div>Topic Two</div>);

    return (<MyParentClass topic={topicTwo} />);
}