React v16.3には、getDerivedStateFromPropsメソッドなど、いくつかの興味深い新機能が導入されています。 この投稿では、その使用方法について説明します。

React v16.3 では、componentWillReceivePropsの代わりにgetDerivedStateFromProps静的ライフサイクルメソッドが導入されました。 componentWillReceivePropsはReactの次のバージョンで間もなく非推奨になるため、コンポーネントをこの新しいメソッドに移動することが重要です。

componentWillReceivePropsと同様に、getDerivedStateFromPropsは、コンポーネントが新しい小道具を受け取るたびに呼び出されます。

componentWillReceiveProps

古いメソッドがどのようになるかのサンプルを次に示します。

// For example purposes only, this is now deprecated

class List extends React.Component {
  componentWillReceiveProps(nextProps) {
    if (nextProps.selected !== this.props.selected) {
      this.setState({ selected: nextProps.selected });
      this.selectNew();
    }
  }

  // ...
}

ご覧のとおり、componentWillReceivePropsは、コンポーネントの状態を更新するためによく使用されます。 this.selectNew()の呼び出しなどの副作用も発生する可能性があります。

getDerivedStateFromProps

新しい方法の動作は少し異なります。

class List extends React.Component {
  static getDerivedStateFromProps(props, state) {
    if (props.selected !== state.selected) {
      return {
        selected: props.selected,
      };
    }

    // Return null if the state hasn't changed
    return null;
  }

  // ...
}

最初の例のようにsetStateを呼び出す代わりに、getDerivedStateFromPropsは単に更新された状態を含むオブジェクトを返します。 この関数には副作用がないことに注意してください。 これは意図的なものです。

getDerivedStateFromPropsは、1回の更新で複数回呼び出される可能性があるため、副作用を回避することが重要です。 代わりに、componentDidUpdateを使用する必要があります。これは、コンポーネントの更新後に1回だけ実行されます。

最終的なコードは次のとおりです。

class List extends React.Component {
  static getDerivedStateFromProps(props, state) {
    if (props.selected !== state.selected) {
      return {
        selected: props.selected,
      };
    }

    // Return null if the state hasn't changed
    return null;
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.selected !== prevProps.selected) {
      this.selectNew();
    }
  }

  // ...
}

まとめ

getDerivedStateFromPropsは、プロップの変更に基づいて、副作用なしに状態を更新することを唯一の目的とする関数を提供することにより、古い方法を改善します。 これにより、コンポーネント全体の推論がはるかに簡単になります。

ただし、派生状態はコンポーネントにいくらかの複雑さを追加し、多くの場合、完全に不要です。 代替案については、投稿おそらく派生状態は必要ありません。