如何将数据从子组件(子组件具有自己的状态)传递给父组件?

时间:2019-06-11 07:47:19

标签: javascript reactjs ecmascript-6

预期效果:单击按钮->调用函数setEditing()-> setEditing()中的调用函数item()-> this.state.isEditing更改为true->父级this.state.isEdit更改为true。当我调用item()函数时,isEditing的值不变

应用

class App extends React.Component {
  constructor() {
    super();

    this.state = {
        isEdit = false; 
    };
  }

  handleSomething = (value) => {
    this.setState(prevState => {
      return {
        isEdit: value
      };
    });
  }


  render() {
    return (
      <div>
        <ul>
          {
            this.state.todos
              .map((todo, index) =>
                <Todo
                  key={index}
                  index={index}
                  todo={todo}
                  handleSomething={this.handleSomething}
                />
              )
          }
        </ul>
      </div>
    );
  }
}

Todo

class Todo extends Component {

  state = {
    isEditing: false
  }

  setEditing = () => {
    this.setState({
      isEditing: !this.state.isEditing
    })

    this.item();
  }

  item = () => { 
    const { isEditing} = this.state;
    this.props.handleSomething(isEditing);
  }

  render() {
    return ( 
        <button onClick={() => this.setEditing()}>Edit</button>

    )
  }
}

3 个答案:

答案 0 :(得分:2)

状态更改后,您需要致电this.item,例如

setEditing = () => {
  this.setState({
    isEditing: !this.state.isEditing
  }, this.item)
}

此外,如果您想从旧状态派生新状态,则必须使用类似以下内容的方法:

setEditing = () => {
  this.setState(prevState => ({
    isEditing: !prevState.isEditing
  }), this.item)
}

答案 1 :(得分:1)

尝试根据先前的状态更改状态,并在回调中调用父函数:

setEditing = () => {
  this.setState(prevState => ({
    isEditing: !prevState.isEditing
  }), this.item)
}

因为如React文档中所述:

  

setState()并不总是立即更新组件。它可能   批处理或将更新推迟到以后。这使得阅读this.state   在调用setState()之后立即发生潜在的陷阱。相反,使用   componentDidUpdate或setState回调(setState(updater,   回调)),保证在更新后都会触发   已应用。如果您需要根据之前的状态设置状态   状态,请阅读下面的updater参数。   (https://reactjs.org/docs/react-component.html#setstate

答案 2 :(得分:0)

class Todo extends React.Component {

  state = {
    isEditing: false
  }

  setEditing = () => {
    this.setState({
      isEditing: !this.state.isEditing
    },this.item())
  }

  item = () => { 
    const { isEditing} = this.state;
    this.props.handleSomething(isEditing);
  }

  render() {
    return ( 
        <button onClick={() => this.setEditing()}>
          Edit
         </button>
    )
  }
}

class App extends React.Component {
  constructor() {
    super();

    this.state = {
        isEdit : false,
        todos : [
          "test 1",
          "test 2"
        ]
    };
  }

  handleSomething = (value) => {
    this.setState(prevState => {
      return {
        isEdit: value
      };
    });
  }


  render() {
    return (
      <div>
        <ul>
          {
            this.state.todos
              .map((todo, index) =>
                <Todo
                  key={index}
                  index={index}
                  todo={todo}
                  handleSomething={this.handleSomething}
                />
              )
          }
        </ul>
      </div>
    );
  }
}

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