React を使用する場合、他の状態やプロパティに基づいて値を変換または導出する必要がある状況によく遭遇します。この概念は 派生状態 として知られており、正しく使用すれば、React ツールキットの中で最も強力なツールの 1 つとなります。
「派生状態: 既存の状態またはプロップから計算できる状態は、派生状態と呼ばれます。」
それでは、本題に飛び込んで、少し楽しんでみましょう。
典型的な「おっと、これはよく考えていませんでした」の例から始めましょう。製品のリストがあり、ユーザーが検索入力に入力した内容に基づいて製品をフィルタリングしたいと想像してください。理想的な世界では、検索は動的に更新され、非常に高速になるはずです。ただし、最初に悪い習慣のアプローチを簡単に見てみましょう。
これが私たちがすべきではない方法です:
import React, { useState } from 'react'; const ProductList = () => { const [searchQuery, setSearchQuery] = useState(''); const [products, setProducts] = useState([ { id: 1, name: 'Laptop' }, { id: 2, name: 'Smartphone' }, { id: 3, name: 'Headphones' }, { id: 4, name: 'Smartwatch' }, ]); const [filteredProducts, setFilteredProducts] = useState(products); const handleSearch = (e) => { const query = e.target.value; setSearchQuery(query); setFilteredProducts( products.filter(product => product.name.toLowerCase().includes(query.toLowerCase()) ) ); }; return ( <div> <input type="text" value={searchQuery} onChange={handleSearch} placeholder="Search for a product" /> <ul> {filteredProducts.map((product) => ( <li key={product.id}>{product.name}</li> ))} </ul> </div> ); }; export default ProductList;
なぜこれが悪い習慣なのでしょうか?
効果があるように見えますね?検索入力が接続され、期待どおりに製品がフィルタリングされます。
しかし、ここに問題があります。フィルタリングされた製品を別の状態として保存しているのです。これにより、データの不必要な重複が発生します。すでに製品が状態にあり、フィルター操作の結果を別の状態に保存しているため、潜在的なバグが発生し、メモリ使用量が増加し、すべてを同期させることが難しくなります。
基本的に、私たちは物事を必要以上に複雑にしています。
ここで、React の知恵を少し適用し、派生状態を使用して上記のコードを修正しましょう。
今回は、2 つの個別の状態変数 (products と filteredProducts) を保持する代わりに、searchQuery に基づいて products 配列からフィルターされた製品を直接導出します。このようにして、冗長性を回避し、状態をクリーンに保ちます。
これが改良版です:
import React, { useState } from 'react'; const ProductList = () => { const [searchQuery, setSearchQuery] = useState(''); const products = [ { id: 1, name: 'Laptop' }, { id: 2, name: 'Smartphone' }, { id: 3, name: 'Headphones' }, { id: 4, name: 'Smartwatch' }, ]; // Derived state: filter products based on the search query const filteredProducts = products.filter(product => product.name.toLowerCase().includes(searchQuery.toLowerCase()) ); const handleSearch = (e) => { setSearchQuery(e.target.value); }; return ( <div> <input type="text" value={searchQuery} onChange={handleSearch} placeholder="Search for a product" /> <ul> {filteredProducts.map((product) => ( <li key={product.id}>{product.name}</li> ))} </ul> </div> ); }; export default ProductList;
改善点は何ですか?
このアプローチは、派生状態を利用しており、フィルタリングされたデータの追加コピーを保存するのではなく、フィルタリングされた積が既存のデータから計算されます。
多くの場合、派生状態が最良の選択ですが、それがすべてに対する特効薬ではありません。コンポーネントがアプリケーションの複数の部分にわたって必要な複雑な計算や状態を処理している場合は、メモ化 を使用するか、派生した状態を上位レベルのコンポーネントまたはコンテキストに保存する方が良い場合があります。
ただし、単純なフィルタリング、並べ替え、またはその他の軽量な派生値の場合は、上記の例が頼りになるアプローチです。
要約すると、React の派生状態とは、物事を DRY に保つ ことです。繰り返しはしないでください。同じデータの不必要なコピーを状態に保持するのではなく、既存の状態とプロパティに基づいてその場で値を計算します。これにより、コードがよりクリーンで効率的になり、保守が容易になります。したがって、次回 React でデータを複製したくなったら、他のソースから直接データを計算できるかどうかを検討してください。未来のあなたはあなたに感謝するでしょう!
以上がReact さん、派生状態について話さなければなりません!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。