reactjs给我一个不变的违规错误,用于通过回调更改父级的状态

时间:2016-03-12 23:16:44

标签: reactjs

以下代码将导致未被捕获的错误: Uncaught Error: Invariant Violation: setState(...): Cannot update during an existing state transition (such as within呈现). Render methods should be a pure function of props and state.

      var NavHabit = React.createClass(
    {
      getInitialState: function(){
        return{
          pageNum: 1
        }
      },

      handleUserClick: function(pageNum){
        this.setState({
          pageNum: this.state.pageNum + pageNum
        });
      },

      render: function(){
        return (
          <div>
          <PageNav onUserClick={this.handleUserClick} />
          <h1>Page: {this.state.pageNum} </h1>
          </div>
        )
      }
    });

  var PageNav = React.createClass({
    handleClicks: function(page){
      this.props.onUserClick(page);
    },

    render: function(){
      return(
        <div id = "page_nav">
            <ul class="pagination text-right" role="navigation" aria-label="Pagination">
                <li class="pagination-previous disabled" onClick={this.handleClicks(-1)} >Previous</li>
                <li class="pagination-next" onClick={this.handleClicks(1)} ><a href="#">Next</a></li>
            </ul>
        </div>
      );
    }
  });

我按照这个例子:http://codepen.io/kenwheeler/pen/kxrDu 但是我使用回调函数并从子项更改父项的状态。我如何解决我的这个问题?

1 个答案:

答案 0 :(得分:1)

PageNav类中存在问题。您的渲染函数实际上正在执行this.handleClicks而不是将其绑定以便稍后调用。通过在函数之后包括括号,它将执行它。

您可以通过以下两种方式之一获得所需的结果。绑定函数的参数或将其包装在另一个函数中。

// Option 1: Bind the function's first parameter
render: function(){
  return(
    <div id = "page_nav">
        <ul class="pagination text-right" role="navigation" aria-label="Pagination">
            <li class="pagination-previous disabled" onClick={this.handleClicks.bind(this, -1)} >Previous</li>
            <li class="pagination-next" onClick={this.handleClicks.bind(this, 1)} ><a href="#">Next</a></li>
        </ul>
    </div>
  );
}


// Option 2: Wrapping in another function 
// (can be on React class or just inline in the render. 
// Putting it inline like this means it gets created each time render is called 
// so I recommend putting it on the React class
render: function(){
  var minus = function() {
       this.handleClicks(-1);
  };
  var plus = function() {
       this.handleClicks(1);
  };

  return(
    <div id = "page_nav">
        <ul class="pagination text-right" role="navigation" aria-label="Pagination">
            <li class="pagination-previous disabled" onClick={minus} >Previous</li>
            <li class="pagination-next" onClick={plus} ><a href="#">Next</a></li>
        </ul>
    </div>
  );
}