ホームページ >ウェブフロントエンド >jsチュートリアル >React があなたを驚かせる理由 (そしてそれを制御する方法)

React があなたを驚かせる理由 (そしてそれを制御する方法)

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-19 14:40:12316ブラウズ

Why React Can Surprise You (And How to Tame It)

React を使ったことがある人なら、おそらく自分に自信が持てない瞬間があったでしょう。私もその経験がありました。何か根本的なことが欠けているのではないかと思いましたが、問題は私にあるのではなく、React の特性にあることがわかりました。

ここでは、これらの予期せぬ行動のいくつかとその背後にある理由、そして私自身の経験を共有します。これで、私が耐えてきた頭を悩ませることが少しでも軽減されることを願っています!


1. 状態の更新: 遅延した反応

setState を呼び出しても、UI はすぐには変わりません。なぜ? React はパフォーマンスのために状態の更新をバッチ処理します。これは、即時のフィードバックの期待に反するため、新しい開発者を不意を突いてしまうことがよくあります。

const [count, setCount] = useState(0);

const handleClick = () => {
  setCount(count + 1);
  console.log(count); // Still logs the old count
};

それが起こる理由:
React の状態更新は非同期です。これにより、React は再レンダリングを最適化できますが、setState がカウントをすぐに更新しないことを意味します。新しい状態は、コンポーネントが再レンダリングされた後にのみ反映されます。

プロのヒント: 古い状態に依存しないようにするには、setState の関数形式を使用します:

setCount(prevCount => prevCount + 1);

2. フック内の依存関係配列: なぜこれが再実行されなかったのですか?

もう 1 つのよくある落とし穴: useEffect フックを追加しましたが、期待どおりに実行されないようです。

useEffect(() => {
  console.log("Effect ran");
}, [someVar]);

その後、someVar を更新しても効果がトリガーされないことがわかります。デバッグ後、someVar がオブジェクトまたは配列であることがわかります。

それが起こる理由:
React の依存関係配列は参照の等価性を使用します。 2 つのオブジェクトまたは配列が同一に見える場合でも、参照が異なる場合は異なるものとみなされます。注意しないと、予期しない動作が発生する可能性があります。

プロのヒント: useDeepCompareEffect などのユーティリティを使用するか、依存関係をメモ化します。


3. 再レンダリングの問題: なぜこれが再レンダリングされたのですか?

コンポーネントを最適化しましたが、依然として不必要に再レンダリングが行われていることがわかりました。

const MyComponent = ({ count }) => {
  console.log("Rendered");
  return <div>{count}</div>;
};

カウントが変化しない場合でも、親コンポーネントが再レンダリングして新しい prop 参照を渡すため、コンポーネントは再レンダリングされます。

それが起こる理由:
React のデフォルトの動作では、React.memo のような最適化を使用しない限り、子コンポーネントが再レンダリングされます。

プロのヒント: React.memo を使用してコンポーネントをメモ化するか、Callback を使用してプロップ参照が不必要に変更されるのを防ぎます。


4. 重要な小道具: 何が重要ですか?

リスト項目にキーを追加するのを忘れると、突然 UI が不安定に動作します。

const [count, setCount] = useState(0);

const handleClick = () => {
  setCount(count + 1);
  console.log(count); // Still logs the old count
};

それが起こる理由:
React はキーを使用して、どの項目が変更、追加、または削除されたかを追跡します。一意のキーがないと、React は DOM ノードを誤って再利用する可能性があります。

プロのヒント: 一意の識別子をキーとして使用します (データの ID など)。


5. イベント処理: 謎のダブルトリガー

ボタンのクリック イベントが 2 回発生し、ブラウザが憑依されているのではないかと思ったことはありますか?

setCount(prevCount => prevCount + 1);

ボタンをクリックすると、「クリックされました!」開発モードではコンソールに 2 回表示されます。

なぜそれが起こるのか:
React の Strict モードでは、潜在的な副作用を強調するために、開発中に意図的にコンポーネントを 2 回マウントおよびアンマウントします。これにより、イベント ハンドラーが複数回起動される可能性があります。

プロからのヒント: パニックにならないでください。これは開発中です。


6. 制御されていないコンポーネント: ここで制御しているのは誰ですか?

入力要素を作成して値を割り当て、React がそれをシームレスに管理すると期待しますが、警告が表示されます。

useEffect(() => {
  console.log("Effect ran");
}, [someVar]);

それが起こる理由:
React は、制御されたコンポーネント (React 状態によって管理される) と制御されないコンポーネント (DOM によって管理される) を区別します。 2 つを混合すると問題が発生します。

プロのヒント: 制御されたコンポーネントが必要な場合は、値を必ず onChange とペアにしてください:

const MyComponent = ({ count }) => {
  console.log("Rendered");
  return <div>{count}</div>;
};

7. 参考文献: なぜ通常の変数を使用できないのですか?

変数を使用してレンダリングの間に値を保存しようとしましたが、毎回リセットされてしまいます。

<ul>
  {items.map(item => (
    <li>{item}</li>
  ))}
</ul>

なぜそれが起こるのか:
React はレンダリングごとに変数を再初期化します。永続的な値の場合は、useRef:
を使用します。

<button onClick={() => console.log("Clicked!")}>Click Me</button>

最後に

「理由」がわかれば、ただ反応するだけではなく、コントロールできるようになります。 React は素晴らしいものですが、少しわかりにくい場合もあります。なぜ物事がそのように機能するのかを理解すると、イライラが軽減されます。問題が発生する理由がわかれば、多くの時間とフラストレーションを節約できます。それはすべて、そのユニークな (そして時には混乱を招く) 魅力の一部です。

以上がReact があなたを驚かせる理由 (そしてそれを制御する方法)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。