在ReactJS中将道具从一个组件传递到另一个组件将返回未定义

时间:2018-10-12 10:34:29

标签: javascript reactjs components

我是React的新手,我正在尝试将道具从一个React组件传递到另一个组件。请考虑下面的代码,并告诉我可能会做错什么。 您会注意到,我正在尝试使用this.props.value进行操作,但是我在控制台中得到的只是“未定义”。我设法通过将所有HTML元素放在一个组件中来运行代码,并且运行良好。

class Editor extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      input: defaultTxt
    };
    this.inputChanges = this.inputChanges.bind(this);
  }

  inputChanges(e) {
    this.setState({
      input: e.target.value
    });
  }

  render() {
    return (
      <div>
        <div id="editorBar">
          Editor
          <i className="fa fa-expand expand" />
        </div>
        <textarea
          id="editor"
          style={editorStyle}
          value={this.state.input}
          onChange={this.inputChanges}
          placeholder={defaultTxt}
        />
      </div>
    );
  }
}

//preview

class Previewer extends React.Component {
  render() {
    return (
      <div>
        <div id="previewerBar">
          Preview
          <i className="fa fa-expand expand" />
        </div>
        <div
          id="preview"
          style={viewerStyle}
          dangerouslySetInnerHTML={{ __html: this.props.value }}
        />
      </div>
    );
  }
}

//wrapper

class Wrapper extends React.Component {
  render() {
    return (
      <div id="wrapper">
        <Editor />
        <Previewer />
      </div>
    );
  }
}

const defaultTxt = `Some default text`;

ReactDOM.render(<Wrapper />, document.getElementById('root'));

2 个答案:

答案 0 :(得分:1)

它应该像这样:

class Editor extends React.Component {
  render() {
    return (
      <div>
        <div id="editorBar">
          Editor
          <i className="fa fa-expand expand" />
        </div>
        <textarea
          id="editor"
          style={editorStyle}
          value={this.props.input}
          onChange={this.props.inputChanges}
          placeholder={defaultTxt}
        />
      </div>
    );
  }
}

//preview

class Previewer extends React.Component {
  render() {
    return (
      <div>
        <div id="previewerBar">
          Preview
          <i className="fa fa-expand expand" />
        </div>
        <div
          id="preview"
          style={viewerStyle}
          dangerouslySetInnerHTML={{ __html: this.props.value }}
        />
      </div>
    );
  }
}

//wrapper

class Wrapper extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      input: defaultTxt
    };
    this.inputChanges = this.inputChanges.bind(this);
  }

  inputChanges(e) {
    this.setState({
      input: e.target.value
    });
  }

  render() {
    return (
      <div id="wrapper">
        <Editor input={this.state.input} inputChanges={this.inputChanges}/>
        <Previewer value={this.state.input}/>
      </div>
    );
  }
}

const defaultTxt = `Some default text`;

ReactDOM.render(<Wrapper />, document.getElementById('root'));

这个想法是Wrapper component是保持状态并控制状态改变的那个。编辑器和预览器是其子级,它们接收数据以显示和调用回调道具。

答案 1 :(得分:1)

如果两个组件共享状态,则将状态提升到父组件-在这种情况下为Wrapper。而且由于这两个子组件都没有状态,因此可以将它们编码为无状态函数。

function Editor({ text, handleChange }) {
  return (
    <div>
      <div id="editorBar">Editor
        <i className="fa fa-expand expand" />
      </div>
      <textarea id="editor" value={text} onChange={handleChange} />
    </div>
  );
}

function Previewer({ text }) {
  return (
    <div>
      <div id="previewerBar">Preview
        <i className="fa fa-expand expand"></i>
      </div>
      <div id="preview" dangerouslySetInnerHTML={{__html: text}}></div>
    </div>
  );
}

class Wrapper extends React.Component {

  constructor(props) {
    super(props);
    this.state={ input: props.defaultText }
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({ input: e.target.value });
  }

  render() {
    return (
      <div id="wrapper">
        <Editor text={this.state.input} handleChange={this.handleChange} />
        <Previewer text={this.state.input} />
      </div>
    );
  }
}

const defaultText = 'Some default text';

ReactDOM.render(<Wrapper defaultText={defaultText} />, document.getElementById('root'));
<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="root"></div>