如何使用生命周期方法getDerivedStateFromProps而不是componentWillReceiveProps

时间:2018-04-02 19:24:34

标签: javascript reactjs lifecycle

看来componentWillReceiveProps将在即将发布的版本中完全淘汰,转而采用新的生命周期方法getDerivedStateFromProps

https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

经过检查,您似乎无法在this.propsnextProps之间进行直接比较,就像在componentWillReceiveProps中一样。有没有办法解决这个问题?

此外,它现在返回一个对象。我是否正确地假设返回值基本上是this.setState

以下是我在网上找到的一个例子 https://github.com/reactjs/rfcs/blob/master/text/0006-static-lifecycle-methods.md#state-derived-from-propsstate

之前

class ExampleComponent extends React.Component {
  state = {
    derivedData: computeDerivedState(this.props)
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.someValue !== nextProps.someValue) {
      this.setState({
        derivedData: computeDerivedState(nextProps)
      });
    }
  }
}

class ExampleComponent extends React.Component {
  // Initialize state in constructor,
  // Or with a property initializer.
  state = {};

  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.someMirroredValue !== nextProps.someValue) {
      return {
        derivedData: computeDerivedState(nextProps),
        someMirroredValue: nextProps.someValue
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}

4 个答案:

答案 0 :(得分:60)

关于componentWillReceiveProps的删除:您应该能够使用getDerivedStateFromPropscomponentDidUpdate的组合处理其用途,请参阅the React blog post例如迁移。是的,getDerivedStateFromProps返回的对象更新状态与传递给setState的对象类似。

如果您确实需要支柱的旧值,您可以随时将其缓存在您的状态中:

state = { cachedSomeProp: null };

static getDerivedStateFromProps(nextProps, prevState) {
  // do things with nextProps.someProp and prevState.cachedSomeProp
  return {
    cachedSomeProp: nextProps.someProp,
    ..
  };
}

任何不会影响州的事情都可以放在componentDidUpdate中,甚至还有getSnapshotBeforeUpdate用于非常低级别的内容。

更新:要了解新的(和旧的)生命周期方法,react-lifecycle-visualizer包可能会有所帮助。

答案 1 :(得分:28)

我们 recently posted on the React blog在绝大多数情况下您根本不需要getDerivedStateFromProps

如果您只想计算一些派生数据,请:

  1. render
  2. 内执行此操作
  3. 或者,如果重新计算它很昂贵,请使用memoize-one等备忘助手。
  4. 这是最简单的"之后"例如:

    import memoize from "memoize-one";
    
    class ExampleComponent extends React.Component {
      getDerivedData = memoize(computeDerivedState);
    
      render() {
        const derivedData = this.getDerivedData(this.props.someValue);
        // ...
      }
    }
    

    查看 this section of the blog post 了解详情。

答案 2 :(得分:2)

如丹·阿布拉莫夫(Dan Abramov)所说

  

直接在渲染器内完成

我们实际上将这种方法与备忘录一起用于任何用于状态计算的代理道具。

我们的代码看起来像这样

// ./decorators/memoized.js  
import memoizeOne from 'memoize-one';

export function memoized(target, key, descriptor) {
  descriptor.value = memoizeOne(descriptor.value);
  return descriptor;
}

// ./components/exampleComponent.js
import React from 'react';
import { memoized } from 'src/decorators';

class ExampleComponent extends React.Component {
  buildValuesFromProps() {
    const {
      watchedProp1,
      watchedProp2,
      watchedProp3,
      watchedProp4,
      watchedProp5,
    } = this.props
    return {
      value1: buildValue1(watchedProp1, watchedProp2),
      value2: buildValue2(watchedProp1, watchedProp3, watchedProp5),
      value3: buildValue3(watchedProp3, watchedProp4, watchedProp5),
    }
  }

  @memoized
  buildValue1(watchedProp1, watchedProp2) {
    return ...;
  }

  @memoized
  buildValue2(watchedProp1, watchedProp3, watchedProp5) {
    return ...;
  }

  @memoized
  buildValue3(watchedProp3, watchedProp4, watchedProp5) {
    return ...;
  }

  render() {
    const {
      value1,
      value2,
      value3
    } = this.buildValuesFromProps();

    return (
      <div>
        <Component1 value={value1}>
        <Component2 value={value2}>
        <Component3 value={value3}>
      </div>
    );
  }
}

它的好处是您不需要在getDerivedStateFromPropscomponentWillReceiveProps内编写大量的比较样板,并且可以跳过构造函数内的复制粘贴初始化。

注意:

这种方法仅用于将道具代理到状态,以防万一您有一些内部状态逻辑,它仍然需要在组件生命周期中进行处理。

答案 3 :(得分:0)

getDerivedStateFromProps 用于需要在渲染之前更新状态并使用道具条件进行更新的情况

GetDerivedStateFromPropd借助道具值更新统计值

阅读https://www.w3schools.com/REACT/react_lifecycle.asp#:~:text=Lifecycle%20of%20Components,Mounting%2C%20Updating%2C%20and%20Unmounting