【问题标题】:Can´t write into state in componentWillReceiveProps无法写入 componentWillReceiveProps 中的状态
【发布时间】:2016-11-09 17:03:57
【问题描述】:

我在组件状态下将通过 nextProps 接收到的一些值写入 componentWillReceiveProps() 时遇到问题。

这是我当前的代码:

componentWillReceiveProps(nextProps){
    console.log("REV")
    console.log(nextProps)
    const dateFrom = nextProps.requestDateFrom;
    if(nextProps.requestDateFrom != 'undefined'){
        this.setState({
            dateFrom: dateFrom,
            dateTo: nextProps.requestDateTo
        });

        //console.log(nextProps.requestDateFrom)
        this.calculateDays();
    }

}

calculateDays(){
    console.log("clas")
    console.log(this.state.dateFrom)

}

我不明白为什么会发生这种情况,因为数据在 nextProps 中,并且 const dateFrom 填充在 componentWillReceiveProps() 中。但是当我尝试在calculateDays() 中访问它们时,状态为空。

当然,我可以只将值作为参数传递给函数,但更愿意让它们处于状态,这样我就可以在其他方法中访问它们。

我在这里错过了什么?

谢谢

【问题讨论】:

  • facebook.github.io/react/docs/component-api.html#setstate setState() 不会立即改变 this.state
  • 在代码周围使用``,而不是''来格式化代码。
  • @BayLife 你能把你的逻辑放到render 函数中吗?这至少可以确保正确性,以防状态从未按时更新。
  • @BayLife 您能否附加一个等效的onUpdate 处理程序,它将值添加到状态?
  • @BayLife 不,不在渲染中调用 setState()。那太糟了。我说的是附加一个事件处理程序,类似于 onUpdate 的内容,您可以将其附加到您的组件(您可能必须自己创建它,因为它可能不存在于您的组件中)。

标签: javascript reactjs


【解决方案1】:

我认为你应该阅读更多关于 react 的生命周期 Component Specs and Lifecycle

在 componentWillReceiveProps 中调用 this.setState() 不会触发额外的渲染。

您可以运行下面的代码,看看它是如何工作的。

很高兴!

class Hello extends React.Component {
  constructor(props) {
    super()
    this.state = {
      count: 0
      }
  }
  componentWillReceiveProps (nextProps ) {
    console.log(nextProps)
    
    this.setState({
      count: this.state.count ++ 
    })
    console.log('componentWillReceiveProps: ' + this.state.count) 
    // componentWillReceiveProps: 1
    // Calling this.setState() within this function will not trigger an additional render.
  }

  render() {
    console.log(this.state.count) // still 0
    return (
      <h1>{this.props.content}, {this.state.count}</h1>
    )
  }
}

class Outer extends React.Component {
  constructor(props) {
    super()
    this.handler = this.handler.bind(this)
    this.state = {
      content: 'Hello, world! '
    }
  }
  handler() {
    this.setState({
      content: 'Hello Component\'s Props had Changed! '
      })
  }
  render() {
    return (
      <div>
        <Hello {...this.state} />
        <a onClick={this.handler}>change the Hello </a>
      </div>
    )
  }
}


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

【讨论】:

    【解决方案2】:

    你应该使用新的生命周期钩子getDerivedStateFromProps()根据道具塑造新的状态。然后你可以在componentDidUpdate()钩子中调用你的calculateDays。例如:

    static getDerivedStateFromProps(props, state) {
        const dateFrom = props.requestDateFrom;
        if(props.requestDateFrom != 'undefined'){
            return {
                dateFrom: dateFrom,
                dateTo: props.requestDateTo
            };
         }
         return null;
    }
    
    componentDidUpdate() {
        this.calculateDays();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 2018-06-10
      • 2012-09-12
      • 1970-01-01
      相关资源
      最近更新 更多