React フックは 6 年前にリリースされましたが、今日に至るまで、上級の React エンジニアでさえもエラーがコミットされているのが確認できます。最新バージョンの React ドキュメントでは、コア チームが useEffect の間違った使用例を教えることに熱心に取り組んでいますが、実際のプロジェクトではエラーが引き続き発生しています。
この投稿では、別のアプローチを試してみましょう。 React と派生の関係と、それをもっと使用する必要がある理由を理解しましょう。
React は完全にリアクティブではありませんが、結局のところ、アプリを作成する開発者にとってはそれほど重要ではありません。ここでの違いは、React が従う粗粒度のアプローチにより、状態遷移によってどのような変化が生じたのかを実際に特定するために再レンダリングが必要になるということです。
それでは、次のような単純な React コンポーネントで考えてみましょう。
function Example() { const [count, setCount] = useState(0) const text = `count is ${count}`; return ( <button onClick={() => setCount((count) => count + 1)}> {text} </button> ); }
setCount を呼び出してカウント状態を変更すると、状態値が更新され、再レンダリングがスケジュールされます。わかりました。React はこのコンポーネントを再度呼び出して再レンダリングします。この時点で、レンダリングで何が変わったのかを React に尋ねたら、何と答えるべきでしょうか?
おそらく謙虚な 「わかりません」。
React は、他のきめ細かいリアクティブ ライブラリのように、依存関係を管理する複雑なデータ構造で状態を追跡しません。 React はコンポーネントを再度呼び出す必要があります。この新しい呼び出しでは、作成されたカウント定数は新しい値を持ち、その上に文字列を含む新しい定数を作成します。たとえば、カウント値が 1 に変更された場合は、“count is 1”
。 🎜>その後、JSX は 1 つの変更を加えて構造を生成します。ボタンの内部テキストは 「count is 1」 ではありません。React は調整プロセスを実行し、この変更を識別して実際の DOM に適用します。当然ですよね?
現時点で、React に何が変更されたかを尋ねると、おそらく次のように答えるでしょう: 「サンプル コンポーネントのボタン テキスト」.
しかし、テキスト定数についてはどうでしょうか?同様に変化しました。なぜそれが作成した v-dom (この用語の問題点は知っていますが、一般的にはこう呼ばれています) 構造だけが重要なのでしょうか?
React の場合、内部で作成した変数と定数は関係ありません。重要なのは、状態が変化し、その後コンポーネント呼び出しが返されることです。
真ん中にあるものはすべて、ビュー構造を作成するプロセスの一部です。もちろん、このすべてのデータは返される JSX に影響を与える可能性があり、コンポーネント呼び出しの結果を考慮し、ビューに応じて DOM を更新することが React モデルのポイントです。
おそらく React モデルが次のように単純化されたことがわかります:
function Example() { const [count, setCount] = useState(0) const text = `count is ${count}`; return ( <button onClick={() => setCount((count) => count + 1)}> {text} </button> ); }
状態の関数の結果として表示します。この場合のビューは、状態に基づいて変化する派生です。したがって、この用語と内部コンポーネント データに関しては、React は派生マシンです。
コンポーネント内で作成したすべての変数と定数は、コンポーネントの呼び出し中にそのまま有効になります。上で使用した例では、サンプル コンポーネントを再レンダリングするたびに、新しい定数テキストが作成されました。プロパティまたは状態に基づいて新しい値が必要な場合は、計算でそれらの状態とプロパティを使用して新しい変数を作成するだけです。
React ドキュメントから例を見てみましょう:
view= f(state)
ここでいくつかの問題があります。まず第一に、国家の性質です。
アプリにこのようなローカル状態が必要なのはなぜですか?データを保持し、ユーザーが変更できるようにするため。 fullName 状態はユーザーによって変更されるのではなく、useEffect によって変更されます。他の状態を使用して新しい値を作成しています。繰り返しますが、React では、コンポーネント内で内部的に作成するすべての変数と定数は、状態とプロパティを使用してその値を計算できます: 派生、React のデフォルトの動作.
この例には、実行時間に関して別の問題があります。この場合、最初のレンダリングでは、fullName 値は空の文字列になります。 React は、このコンポーネントの JSX の戻り値を取得し、それを UI にレンダリングし、ブラウザーの描画プロセスに従い、その後、コンポーネントの useEffects を呼び出します。この時点で、setfullName 呼び出しが行われ、新しい再レンダリングがスケジュールされます。 React は、フルネームを Taylor Swift としてコンポーネントを再度呼び出し、新しいテキスト値で UI を更新します。
ランタイムの観点から見ると、2 つのレンダリングを実行しており、そのうちの 1 つは間違ったデータを使用した不要なレンダリングです。ユーザーには値が空として表示され、視覚的なバグとして認識される可能性があるため、パフォーマンスと安定性の点でさらに悪くなります。
したがって、React 派生モデルに従って、単純に次のように変更できます。
function Form() { const [firstName, setFirstName] = useState('Taylor'); const [lastName, setLastName] = useState('Swift'); // ? Avoid: redundant state and unnecessary Effect const [fullName, setFullName] = useState(''); useEffect(() => { setFullName(firstName + ' ' + lastName); }, [firstName, lastName]); //... return <span>{fullName}</span>; }
これで、レンダリングは 1 つだけになり、不要なレンダリングは避けられます。また、派生を使用するだけでエフェクトを使用することは避けます。これは、最新バージョンの状態値を使用して再レンダリングされるたびに更新されます。
そうですね、この場合は useMemo を使用して、useEffect で使用していたものと同じ依存関係の配列を追加するだけです。 React のメモ化モデルは、再レンダリングのたびに新しい派生を作成するというデフォルトの動作を回避するための単なる方法です。 useMemo を使用すると、状態とプロパティを手動で追跡し、それらの一部が変更された場合は派生を再度作成するだけです。
useEffect は値の変更時の外部同期に必要です。 UI 開発では、これが意味のあるケースはほとんどありません。通常、サーバー API 呼び出しなどの外部変更はユーザーのアクションで発生するためです (ちなみに、私たちは ユーザー インターフェース を作成しています)。これらは useEffect 内ではなく、イベント ハンドラー上で発生します。
useEffect を使用して状態を更新している場合は、おそらく派生を使用して同じ更新を実行し、前述したすべての問題を回避できます。
導出が機能しない場合、または数少ない特定のケースの 1 つがある場合、あるいは州の設計またはソリューション自体に何か問題がある場合。それ自体に問題はありませんが、このような場合は、コンポーネントを見直して、コンポーネント コードに関する将来の問題を回避することをお勧めします。
これは React での導出に関する基本ですが、ここで何かが欠けています。
単純な GET リクエストのような、ある状態をパラメータとして使用し、状態が変化するたびに再計算する必要がある非同期の導出を実行する必要がある場合はどうなりますか?
これは次の投稿のトピックです。
また会いましょう!
以上がReact での導出を知りませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。