解决React中“无法在现有状态转换(例如在`render`之内)期间更新”错误的解决方案是什么?

我正在尝试编写一个React应用,其中父组件将回调函数传递给子组件,回调函数被调用并传递参数,并且它会更新父组件中的状态变量,并将其设置为参数。但是我一直遇到这个错误:

Warning: Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.

我在这里发现了其他有关此问题的问题,并已阅读了有关错误含义的解释,但是有关如何解决该错误的所有解释都涉及更复杂的组件结构,我刚开始时就很难遵循与React。我希望有人能向我展示如何修改此简单的组件结构以执行我想做的事情,同时避免出现该错误(如果重要的话,我正在codepen.io环境中进行此操作):

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { word: 'hello' }
  }

  myCallback = (dataFromChild) => {
    this.setState({ word: dataFromChild })
  }

  render() {
    return (
      <div>
        <p>{this.state.word}</p>
        <Child callbackFromParent={this.myCallback} />
      </div>
    )
  }
}

function Child(props) {
  return (
    <div>
      <button onClick={props.callbackFromParent('goodbye')}>Say goodbye</button>
    </div>
  )
}

// ========================================

ReactDOM.render(<Parent />, document.getElementById('root'));
评论
  • isit
    isit 回复

    Add a () for myCallback function

    myCallback = dataFromChild => () => {
    

    尝试文本演示:

    function Child(props) {
      return (
        <div>
          <button onClick={props.callbackFromParent("goodbye")}>Say goodbye</button>
        </div>
      );
    }
    
    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = { word: "hello" };
      }
    
      myCallback = dataFromChild => () => {
        this.setState({ word: dataFromChild });
      };
    
      render() {
        return (
          <div>
            <p>{this.state.word}</p>
            <Child callbackFromParent={this.myCallback} />
          </div>
        );
      }
    }
    ReactDOM.render(<App />, document.getElementById("root"));
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>