web-dev-qa-db-ja.com

反応/機能コンポーネント/変更された小道具/ getDerivedStateFromProps

簡単なCRUDアプリを反応させているとしましょう。私のfunctionalコンポーネントは基本的に単なるフォームです。

  • CREATEの場合、小道具を介して空のオブジェクトを渡します
  • UPDATEの場合、propsを介して値を持つオブジェクトを渡します(API呼び出しで親コンポーネントのデータを取得しました)

私はこのように見えます:

const MyForm = (props) => {

 const [myValues, setMyValues] = useState(props.myValues);
 const [errors, setErrors] = useState(0);
 (...)
}

UPDATEの場合、(もちろん)コンポーネントがマウントされたときにprops.myValuesがまだ空であり、親コンポーネントからのAPI呼び出しが完了したときに再度設定(更新)されないため、フォームの値が空のままになるという問題が発生します。

クラスコンポーネントを使用して、getDerivedStateFromProps()で解決します。機能コンポーネントにそのようなものはありますか?または私は最初からこれを間違っていますか?アドバイスをありがとう!

4
Thread Pitt

これを行う別の方法は、 キーを持つ完全に制御されていないコンポーネント 戦略です。そのルートをたどると、コンポーネントは同じままです。

const MyForm = (props) => {

 const [myValues, setMyValues] = useState(props.myValues);
 const [errors, setErrors] = useState(0);
 (...)
}

しかし、その使用法には1つの余分な部分があります。

<MyForm myValues={myValues} key={myValues} />

このようにkeyプロパティを使用すると、myValuesが変更されると、このコンポーネントの新しいインスタンスが作成されます。つまり、内部myValues状態に指定したデフォルト値が新しい値にリセットされますあります。

これにより、useEffectを使用した場合に得られる二重のレンダリングが回避されますが、新しいコンポーネントインスタンスが犠牲になります。個々の入力レベルでこれを行う場合、これは問題にはなりませんが、フォーム全体を再構築したくない場合があります。

1
Rob Allsopp

あなたが書くとき:

const [myValues, setMyValues] = useState(props.myValues);

myValuesプロパティはmyValues状態を初期化するためにのみ使用されます。 Dan Abramovは 彼の最新の記事 のこの点に関連しています。
以下を提案します。
1。 myValuesプロップの名前をinitialValuesに変更します。
2。送信後にAPIを呼び出し、結果に応じて状態を変更します。

次のようになります。

const MyForm = (props) => {
  const { initialValues, onSubmit } = this.props
  const [myValues, setMyValues] = useState(initialValues);
  ...
  const handleSubmit = () => {
     // Assume that onSubmit is a call to Fetch API
     onSubmit(myValues).then(response => response.json())
                       .then(updatedValues => setMyValues(updatedValues)) 
  }
} 
0
Benefits