Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 从何处移动不推荐使用的组件WillReceiveProps()的setState()回调?_Reactjs - Fatal编程技术网

Reactjs 从何处移动不推荐使用的组件WillReceiveProps()的setState()回调?

Reactjs 从何处移动不推荐使用的组件WillReceiveProps()的setState()回调?,reactjs,Reactjs,React 16弃用组件WillReceiveProps()生命周期方法。首选的替换是新的getDerivedStateFromProps()或componentDidUpdate()。现在让我们假设我有一些这样的代码: componentWillReceiveProps(newProps) { if (this.props.foo !== newProps.foo) { this.setState({foo: newProps.foo}, () => this.handleN

React 16弃用
组件WillReceiveProps()
生命周期方法。首选的替换是新的
getDerivedStateFromProps()
componentDidUpdate()
。现在让我们假设我有一些这样的代码:

componentWillReceiveProps(newProps) {
  if (this.props.foo !== newProps.foo) {
    this.setState({foo: newProps.foo}, () => this.handleNewFoo()});
  }
}
getDerivedStateFromProps(newProps, prevState) {
  if (this.props.foo !== newProps.foo) {
    return {foo: newProps.foo};
  } else {
    return null;
  }
}
我可以尝试将代码移动到
getDerivedStateFromProps()
,如下所示:

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

但是如何处理来自
setState()
的回调呢?将其移动到
componentdiddupdate
是唯一的选项吗?我宁愿在
render()
之前调用
this.handleNewFoo()
,以避免两次渲染的视觉和性能成本。

如果您还没有读过这篇博文,您应该

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

  • 这个.handleNewFoo方法是做什么的? 你在handleNewFoo内进行另一次设置状态吗?如果是,则会触发多个渲染调用

  • 例如

    如果您没有在handleNewFoo内执行任何设置状态,那么请自问是否必须在道具更改时调用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
    }
    
    这完全取决于你在这里面做什么

    编辑:

    上面的代码不起作用,因为@Darko提到的
    getDerivedStateFromProps
    是静态方法,您无法访问其中的
    this
    。而且您无法在
    getDerivedStateFromProps
    中获取以前的道具。所以这个答案是完全错误的

    一种解决方案是使用
    useffect

    useEffect(() => {
      setState(...)
    }, [props.foo])
    

    每当更改
    props.foo
    时,就会调用此
    useffect
    。此外,组件将被渲染两次,一次用于道具更改,另一次用于
    setState
    内部
    useffect
    。只需小心
    setState
    内部的
    useffect
    ,因为它会导致无限循环。

    这个.handleNewFoo()
    无论如何都会在渲染后调用。调用
    setState()。无论如何,在重新渲染后调用
    setState
    的回调,因此这与当前实现在性能和重新渲染方面没有什么不同。如果要防止不必要的重新渲染,必须提前计算最终状态。什么是handleNewFoo?请提供所有相关代码。@Chris啊,对了,我错过了。请将其作为答案发布,以便我可以接受。顺便问一下,为什么要删除
    react-16
    标记?这不起作用,因为
    getDerivedStateFromProps
    是一个静态方法,您无法在其中访问
    This