反应:父组件中的功能未从子组件接收数据

时间:2018-08-16 16:30:49

标签: reactjs

我正在使用React开发一个项目,我需要使用子组件的输入来更新父组件的state。我在链中的每个函数中进行了console.log()的操作,发现父组件中的fetchText()函数没有收到文本

这是我的父组件的样子

class AppComponent extends React.Component{
  constructor(props){
    super(props);
    this.state = { markdownText: `` };

    this.fetchText = this.fetchText.bind(this);
  }

  fetchText(text){
    this.setState({ markdownText: text });
    console.log(text);
  }

  render(){
    return(
      <div id="app-grid">
        <h1>Markdown Viewer</h1>
        <MarkDownComponent userInput={this.fetchText} />
        <PreviewComponent />
      </div>
    );
  }
}

“我的孩子”组件看起来像这样

class MarkDownComponent extends React.Component{
  constructor(props){
    super(props);
    this.state = { text: ``};

    this.getInput = this.getInput.bind(this);
    this.sendInput = this.sendInput.bind(this);
  }

  getInput(event){
    this.setState({ text: event.target.value });
    this.sendInput();
  }

  sendInput(){
    this.props.userInput = this.state.text;
    //console.log(this.props.userInput);
  }

  render(){
    return(
      <div id="markdown-component">
        <textarea id="editor" rows="16" onChange={this.getInput}></textarea>
      </div>
    );
  }
}

在子组件中console.log()插入this.props.userInput时,我在键入时会返回该值。这样就表明该值已成为属性,但是为什么它不在父组件中更新?

3 个答案:

答案 0 :(得分:2)

问题是您正在将状态值分配给不正确的函数。

this.props.userInput = this.state.text; // this is incorrect

//Right one

class MarkDownComponent extends React.Component{
  constructor(props){
    super(props);
    this.state = { text: ``};

    this.getInput = this.getInput.bind(this);
    this.sendInput = this.sendInput.bind(this);
  }

  getInput(event){
    this.setState({ text: event.target.value });
    this.sendInput();
  }

  sendInput(){
    this.props.userInput(this.state.text);
    //console.log(this.props.userInput);
  }

  render(){
    return(
      <div id="markdown-component">
        <textarea id="editor" rows="16" onChange={this.getInput}></textarea>
      </div>
    );
  }
}

您可以在getInput函数中直接调用this.props.userInput函数:

class MarkDownComponent extends React.Component{
      constructor(props){
        super(props);
        this.state = { text: ``};

        this.getInput = this.getInput.bind(this);
      }

      getInput(event){
        this.props.userInput(event.target.value);
      }

      render(){
        return(
          <div id="markdown-component">
            <textarea id="editor" rows="16" onChange={this.getInput}></textarea>
          </div>
        );
      }
    }

ES6方式:

class MarkDownComponent extends React.Component{
      constructor(props){
        super(props);
        this.state = { text: ``};
      }

      getInput = (event) => {
        this.props.userInput(this.state.text);
      }

      render(){
        return(
          <div id="markdown-component">
            <textarea id="editor" rows="16" onChange={this.getInput}></textarea>
          </div>
        );
      }
    }

答案 1 :(得分:2)

这里没有什么要注意的:

您无法更改道具的价值,道具会通过其父项传递给组件

this.props.userInput = this.state.text;

这行不通。

因此,要使父级的fetchData从textarea中获取文本,您应该这样做

<textarea id="editor" rows="16" onChange={this.props.userInput}></textarea>

和父组件中:

fetchText(event){
    console.log(event.target.value)
    this.setState({ markdownText: event.target.value });
}

您不需要getInputsendInput之类的函数即可将数据发送到父组件。

答案 2 :(得分:1)

如评论中所述,无需为您的函数分配状态。同样,如果您希望通过Child更改文本,仅此而已,则不需要Child中的状态。如果没有必要,请不要使用状态。

class AppComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { markdownText: "" };

    this.fetchText = this.fetchText.bind(this);
  }

  fetchText(e) {
    this.setState({ markdownText: e.target.value});
  }

  render() {
    return (
      <div id="app-grid">
        <h1>Markdown Viewer</h1>
        Value is now: {this.state.markdownText}
        <MarkDownComponent userInput={this.fetchText} />
      </div>
    );
  }
}

const MarkDownComponent = ( props ) => {
  return (
    <div id="markdown-component">
      <textarea id="editor" rows="16" onChange={props.userInput}></textarea>
    </div>
  )
}

ReactDOM.render(<AppComponent />, 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>