簡體   English   中英

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

[英]How to use lifecycle method getDerivedStateFromProps as opposed to componentWillReceiveProps

看起來componentWillReceiveProps將在即將發布的版本中完全淘汰,取而代之的是新的生命周期方法getDerivedStateFromPropsstatic getDerivedStateFromProps()

經過檢查,您現在似乎無法在this.propsnextProps之間進行直接比較,就像在componentWillReceiveProps 有沒有辦法解決這個問題?

此外,它現在返回一個對象。 我假設返回值本質上是this.setState是否this.setState

下面是我在網上找到的一個例子: State衍生自 props/state

之前

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;
  }
}

關於移除componentWillReceiveProps :您應該能夠結合使用getDerivedStateFromPropscomponentDidUpdate來處理它的使用,請參閱React 博客文章了解遷移示例。 是的, getDerivedStateFromProps返回的對象更新狀態類似於傳遞給setState的對象。

如果你真的需要一個 prop 的舊值,你總是可以用這樣的東西將它緩存在你的狀態中:

state = {
  cachedSomeProp: null
  // ... rest of initial state
};

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

任何不影響狀態的東西都可以放在componentDidUpdate ,甚至還有一個getSnapshotBeforeUpdate用於非常低級的東西。

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

正如我們最近在 React 博客上發布的那樣在絕大多數情況下,您根本不需要getDerivedStateFromProps

如果您只想計算一些派生數據,可以:

  1. 就在render里面render
  2. 或者,如果重新計算它很昂貴,請使用memoize-one類的備忘錄助手。

這是最簡單的“之后”示例:

import memoize from "memoize-one";

class ExampleComponent extends React.Component {
  getDerivedData = memoize(computeDerivedState);

  render() {
    const derivedData = this.getDerivedData(this.props.someValue);
    // ...
  }
}

查看博客文章的這一部分以了解更多信息。

正如丹·阿布拉莫夫所說

就在渲染里面做

我們實際上將這種方法與 memoise one 一起用於任何類型的代理道具以進行狀態計算。

我們的代碼看起來像這樣

// ./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編寫大量的比較樣板,你可以跳過構造函數中的復制粘貼初始化。

注意:

這種方法僅用於將 props 代理到 state,如果您有一些內部狀態邏輯,它仍然需要在組件生命周期中處理。

getDerivedStateFromProps用於在渲染之前更新狀態並使用 props 條件更新

GetDerivedStateFromPropd 在 props 值的幫助下更新統計值

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM