将setState()回调从不推荐使用的componentWillReceiveProps()移到哪里?

时间:2018-09-14 13:58:17

标签: reactjs

反应16不赞成使用componentWillReceiveProps()生命周期方法。首选替换为新的getDerivedStateFromProps()componentDidUpdate()。现在,假设我有一些类似的代码:

componentWillReceiveProps(newProps) {
  if (this.props.foo !== newProps.foo) {
    this.setState({foo: newProps.foo}, () => this.handleNewFoo()});
  }
}

我可以这样尝试将代码移至getDerivedStateFromProps()

getDerivedStateFromProps(newProps, prevState) {
  if (this.props.foo !== newProps.foo) {
    return {foo: newProps.foo};
  } else {
    return null;
  }
}

但是我该如何处理setState()中的回调?将其移动到componentDidUpdate是唯一的选择吗?我宁愿在this.handleNewFoo()之前调用render()来避免两个渲染的视觉和性能开销。

1 个答案:

答案 0 :(得分:-1)

如果您尚未阅读此博客文章,则应 https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state

  1. 如果您只是将props.foo分配给state.foo而没有进行任何计算/处理,那么您需要问自己是否真的需要状态字段。因为您始终可以使用this.props.foo而不是this.state.foo。

  2. this.handleNewFoo方法做什么? 您是否在handleNewFoo中执行另一个setState?如果是,则将触发多个渲染调用。

例如

this.setState({foo: this.props.foo} // one render call, () => this.handleNewFoo())

const handleNewFoo = () => {
  this.setState({ }) // another render call
}

如果您没有在handleNewFoo中执行任何setState操作,请问自己是否必须在更改道具时调用handleNewFoo?

如果您在handleFoo中使用setState,我会建议类似的东西

getDerivedStateFromProps(newProps, prevState) {
  if (this.props.foo !== newProps.foo) {
    return this.handleNewFoo(this.props.foo, prevState);
  } else {
    return prevState;
  }
}

handleNewFoo(foo, state) {
  // do some calculation using foo
  const derivedFoo = state.foo + foo;

  // if your are using immutability_helper library.
  const derivedState = update(state, { foo: {$set:  derivedFoo}});

  return derivedState
}

这一切都取决于您在this.handleNewFoo

中的工作。