关于getDerivedStateFromProps的想法

Huy*_* Vo 2 javascript reactjs react-native

根据这篇帖子关于React 16.3中的新闻,在下一次更新componentWillReceiveProps中将有一个替换,即getDerivedStateFromProps(替换只发生在17.0).

有趣的是,这是一种全新的静态生命周期方法

在初始安装和重新渲染组件时调用,因此您可以使用它而不是基于构造函数中的props创建状态.

我很困惑.所以从现在开始我应该拆分我的构造函数并将创建状态逻辑放到这个新函数中吗?我的意思是当你第一次创建组件创建状态时的逻辑,以及从API props创建状态时的逻辑是不一样的.将它们放在一个方法中似乎不太理想.

还有一件事是,如果我选择从构造函数创建我的状态,那么仍然会调用这个新方法.真是个混蛋!

你怎么看?

Agn*_*ney 11

假设我们有一个列表组件,它通过提供从API的父级接收的一些参数来呈现一些列表项.

  1. 首先我们将this.state.data变量初始化为[].
  2. 然后使用props,我们执行API调用componentDidMount()以将其分配给this.state.data.
  3. 现在,来自父级的这些参数可能会发生变化,因此您必须重复此过程componentWillReceiveProps.

我认为这可能getDerivedStateFromProps是针对性的情景.现在,不需要两次从props更新状态,只需要在函数中编写一次:getDerivedStateFromProps.顾名思义,当必须从道具派生状态时使用它.

要记住的要点:

您仍然需要在构造函数中设置初始状态.初始状态和从道具派生状态的逻辑可能非常不同.例如,如果您没有将data变量初始化为[]并且您正在映射this.state.data它将失败,因为API尚未返回getDerivedStateFromProps尚未设置的结果.

尽管getDerivedStateFromProps不能使用this,但它的工作原理与之相同this.setState.

也就是说,如果你回来了

{
  data: response.data
}
Run Code Online (Sandbox Code Playgroud)

它不会更新您在构造函数中设置的其他状态变量.您也可以选择返回null以表示无变化.

从:

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      externalData: []
    }
  }
  componentWillMount() {
    asyncLoadData(this.props.someId).then(externalData =>
     this.setState({ externalData })
    );
  }
  componentWillReceiveProps() {
    asyncLoadData(this.props.someId).then(externalData =>
     this.setState({ externalData })
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

至:

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      externalData: []
    }
  }
  static deriveStateFromProps(props, state, prevProps) {
    if (prevProps === null || props.someValue !== prevProps.someValue) {
      return {
        derivedData: computeDerivedState(props)
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:我只是从纯React角度注意一个实例.

也读你可能不需要来自React Blog的派生状态.


tom*_*hes 6

关键的区别在于,在React 16中,仅在收到新道具时,不会在初始渲染中调用componentWillReceiveProps.这意味着在您的情况下,您将在构造函数中的第一次加载时创建派生状态,然后在更新时使用componentWillReceiveProps.

使用新的getDerivedStateFromProps,此逻辑只能在此函数中编写,因为它在初始安装更新时运行.

在安装过程中,React不会使用初始道具调用componentWillReceiveProps().如果某些组件的道具可能会更新,它只会调用此方法.调用this.setState()通常不会触发componentWillReceiveProps().

关于你对我的API的问题,这取决于组件的设置方式,在我看来,在父组件中进行API调用是合乎逻辑的,这样你就可以控制道具的传递方式并使接收道具的组件尽可能愚蠢.在进行API调用之后,仍然可以在方法中设置状态.

正如丹·阿布拉莫夫所说,将道具传递给国家通常是一个坏主意,这个功能将很少使用,当你的状态取决于道具如何随时间变化时使用.

道具陈述为反实践潜在用例.

React - componentWillReceiveProps()