ホームページ >ウェブフロントエンド >jsチュートリアル >React 開発でよくある間違いとその回避方法 ⚛️
私は数年間 React アプリケーションを開発してきましたが、プロジェクトの開発を遅らせる数え切れないほどの間違いを経験してきました。
React は、動的ユーザー インターフェイスを構築するための最も人気のあるライブラリの 1 つですが、その柔軟性は、新しい開発者にとってよくある間違いにつながる可能性もあります。
このガイドでは、開発者が React で犯しやすい主な間違いを取り上げ、より適切で効率的なコードを作成するための実用的なヒントを提供します。
飛び込んでみましょう!
続行する前に、まず項目のリストを表示し、追加または削除する React コンポーネントを作成しましょう。
import { useState } from "react"; const Home = (props) => { const [items, setItems] = useState(['item1', 'item2']); const [itemToAdd, setItemToAdd] = useState(''); function wrongHandleAddItem(item) { items.push(item); setItems(items); } function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); } function removeItem(item) { const itemIndex = items.indexOf(item); if (itemIndex !== -1) { const newArray = [...items]; newArray.splice(itemIndex, 1); setItems(newArray); } } return ( <div> <p>Here, I wrote two different methods to add an item in the items state array. Let's break it down together:<br> </p> <pre class="brush:php;toolbar:false">function wrongHandleAddItem(item) { items.push(item); setItems(items); }
このメソッドが最初に行うことは、要素を配列に追加することを目的としたプッシュ配列関数の呼び出しです。
2 番目のことは、setItems を呼び出して状態変数に変更を適用することです。
ただし、このコードを実行しても機能しません ❌
このコードは、非常に重要な React ルール、状態の変更に違反しています。
React は状態変数の ID に依存して、状態がいつ変化したかを判断します。項目を配列にプッシュするとき、その配列の ID は変更されないため、React は値が変更されたことを認識できず、配列を再レンダリングできません。
修正方法は次のとおりです ✅ :
function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); }
このメソッドでは、スプレッド演算子を使用して新しい配列を作成しました。これにより、項目のコンテンツを使用して新しい配列をインスタンス化できます。 2 番目のパラメーターは、新しいコンテンツ (ここの項目) を追加するために使用されます。
最後のステップは、setItems メソッドを呼び出して変数項目の新しい状態を検証することです ✅
すべての React 開発者は、おそらく開発過程で少なくとも 1 回はこのエラーを目にしたことがあるでしょう。
これが発生する最も一般的な方法は、データをマッピングする場合です。この違反の例は次のとおりです:
items.map((item) => ( <div> {item} <button onClick={() => removeItem(item)}>-</button> </div> ))}
要素の配列をレンダリングしたい場合は、各項目を識別できるように React にもう少しコンテキストを与える必要があります。可能な限り最良の場合、一意の識別子である必要があります。
これを簡単に修正する方法は次のとおりですが、これは最適ではありません:
items.map((item, index) => ( <div key={index} > {item} <button onClick={() => removeItem(item)}>-</button> </div> ))}
React の経験を積み、React がどのようにより良く機能するかを理解すると、自分のケースに基づいて React が適切かどうかを判断できるようになります。
これを完璧にするには、crypto.randomUUID() などの UUID ジェネレーターを使用し、次のようにオブジェクトとして項目リストに保存します。
const newItemToAdd = { id: crypto.randomUUID(), value: item }; const newArray = [...items, newItemToAdd]; setItems(newItems);
レンダリング中に次のように使用します:
items.map((item, index) => ( <div key={item.id} > {item.value} <button onClick={() => removeItem(item)}>-</button> </div> ))}
これで完璧です ✅
マウント時に API からデータをフェッチする必要がある関数があるとします。 useEffect フックを使用し、await キーワードを使用します。
最初の試行を確認してみましょう:
ご存知のとおり、await キーワードは async キーワードでマークされた関数内にある必要があります。
import { useState } from "react"; const Home = (props) => { const [items, setItems] = useState(['item1', 'item2']); const [itemToAdd, setItemToAdd] = useState(''); function wrongHandleAddItem(item) { items.push(item); setItems(items); } function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); } function removeItem(item) { const itemIndex = items.indexOf(item); if (itemIndex !== -1) { const newArray = [...items]; newArray.splice(itemIndex, 1); setItems(newArray); } } return ( <div> <p>Here, I wrote two different methods to add an item in the items state array. Let's break it down together:<br> </p> <pre class="brush:php;toolbar:false">function wrongHandleAddItem(item) { items.push(item); setItems(items); }
残念ながら、これは機能せず、次のエラー メッセージが表示されます:
function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); }
これが修正です: useEffect フック内に別の非同期関数を作成します ✅
items.map((item) => ( <div> {item} <button onClick={() => removeItem(item)}>-</button> </div> ))}
async キーワードの意味を理解することが重要です。
オブジェクト json を返すのではなく、オブジェクト json を解決する Promise を返します。
useEffect は Promise を返すことになっていないため、これは実際には問題です。これは (上記のように) 何も返さないか、クリーンアップ関数を返すことを期待しています。クリーンアップ関数は重要ですが、このガイドの範囲外ですが、ここで使用します:
items.map((item, index) => ( <div key={index} > {item} <button onClick={() => removeItem(item)}>-</button> </div> ))}
状態管理に戻って、新しい開発者がよく犯すもう 1 つの興味深い間違いを見てみましょう。これは、React の状態をさらに深く理解するのに役立ちます。
これを説明するために、goodHandleAddItem メソッドを取り上げてみましょう。
const newItemToAdd = { id: crypto.randomUUID(), value: item }; const newArray = [...items, newItemToAdd]; setItems(newItems);
このコードを実行すると、期待した結果がコンソールに記録されないことがわかります。
ここに問題があります: 状態変数のセッター関数は非同期です。
setItems メソッドを呼び出すとき、実際には変数を割り当てているのではなく、更新をスケジュールしています。
これが修正です: newArray 変数で変数の内容が何であるべきかはすでにわかっています。つまり、items 変数の内容であると思われるデータを使用するには、setItems ✅ の後であっても、代わりに変数 newArray
を使用する必要があります。最後のガイドも React の状態管理について説明します。このガイドを読み終えるとあなたもプロになれます! ?
React Hooks を使用する際のよくある落とし穴は、古い状態データの誤用です。これは、連続した状態更新で状態変数を直接参照するときに発生する可能性があります。前のエラーで見たように、状態の更新は非同期である可能性があります。これは、連続する呼び出しで状態変数が参照されるときに、状態変数が最新の値を反映しない可能性があることを意味します。
物事をわかりやすくするために、よく知られたカウンターである新しい例を使用してみましょう:
items.map((item, index) => ( <div key={item.id} > {item.value} <button onClick={() => removeItem(item)}>-</button> </div> ))}
上記の使用法は間違っています。実際、count は setCount 呼び出し内で直接参照されます。イベント ハンドラーとライフサイクル メソッドでは、状態の更新をバッチ処理することができ、両方ともカウントとして同じ初期値を使用するため、最終状態が不正確になります。
物事を機能させるために使用できる setCount の別の形式として、アップデーター関数があります。アップデーター関数は、以前の状態を引数として受け取り、新しい状態を返すため、連続する各更新には正しい値が含まれ、望ましくない動作が防止されます。
使用方法は次のとおりです:
import { useState } from "react"; const Home = (props) => { const [items, setItems] = useState(['item1', 'item2']); const [itemToAdd, setItemToAdd] = useState(''); function wrongHandleAddItem(item) { items.push(item); setItems(items); } function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); } function removeItem(item) { const itemIndex = items.indexOf(item); if (itemIndex !== -1) { const newArray = [...items]; newArray.splice(itemIndex, 1); setItems(newArray); } } return ( <div> <p>Here, I wrote two different methods to add an item in the items state array. Let's break it down together:<br> </p> <pre class="brush:php;toolbar:false">function wrongHandleAddItem(item) { items.push(item); setItems(items); }
count の内容をログに記録すると、正しい値が示されるようになりました ✅
これらのよくある間違いを避けることで、よりパフォーマンスの高い React アプリケーションを開発し、状態管理をマスターできるようになります。
このガイドがお役に立てば幸いです。また、コーディングの時間を楽しく過ごしていただけることを願っています。
新規または確認済みの React 開発者として、このガイドを楽しんでいただけた場合は、「いいね!」を残してください?
また会いましょう!
以上がReact 開発でよくある間違いとその回避方法 ⚛️の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。