すべてに「useState」が本当に必要ですか?代替案の検討

Susan Sarandon
リリース: 2024-10-09 06:20:02
オリジナル
854 人が閲覧しました

Do You Really Need

初めて React に飛び込むと、useState はすべてを機能させる魔法の呪文のように感じられます。クリックを追跡するボタンが必要ですか? useStateを使用します。モーダルを切り替える必要がありますか? useStateを再度使用します。しかし、React 開発をさらに深めていくと、次のような疑問が湧くかもしれません: useState はあらゆる状況に適した選択なのでしょうか?

当然のことながら、答えはノーです。 useState は多用途ですが、React は特定のニーズに応じてより適した他のフックやパターンを提供します。 useRef、useReducer、useContext などの代替手段を検討して、それらがいつ機能するかを見てみましょう。

useState の代わりに useRef を使用する場合

React 初心者の典型的な間違いは、実際にはレンダリングに影響を与えない値に useState を使用することです。 useRef は、再レンダリングをトリガーせずにレンダリング間でデータを保持する必要がある場合に理想的な選択肢です。

実際の例:

ボタンがクリックされた回数を追跡していると想像してください。ただし、コンポーネントを毎回再レンダリングする必要はありません。

function ClickTracker() {
  const clickCount = useRef(0);

  const handleClick = () => {
    clickCount.current += 1;
    console.log(`Button clicked ${clickCount.current} times`);
  };

  return <button onClick={handleClick}>Click me</button>;
}
ログイン後にコピー

この場合、useRef は不必要な再レンダリングを引き起こすことなくクリック数を保持します。 useState を使用した場合、コンポーネントはクリックするたびに再レンダリングされますが、ここでは必要ありません。

useRef を選択する場合:

  • UI 更新をトリガーする必要のない値を追跡します。
  • DOM 要素または以前の状態の値への参照を保存します。

useReducer が useState 上で輝くとき

より複雑な状態ロジックの場合、特に状態に複数のサブ値またはアクションが含まれる場合、useReducer が強力な代替手段となる可能性があります。 useState は、相互に依存する状態のいくつかの部分を管理している場合、扱いにくく感じられるかもしれません。

現実世界のシナリオ:

名前、電子メール、パスワードなどの複数の入力を管理するフォームを構築しているとします。各入力に useState を使用すると、すぐに面倒になってしまう可能性があります。

function formReducer(state, action) {
  switch (action.type) {
    case 'SET_NAME':
      return { ...state, name: action.payload };
    case 'SET_EMAIL':
      return { ...state, email: action.payload };
    case 'SET_PASSWORD':
      return { ...state, password: action.payload };
    default:
      return state;
  }
}

function SignupForm() {
  const [formState, dispatch] = useReducer(formReducer, {
    name: '',
    email: '',
    password: ''
  });

  return (
    <>
      <input
        value={formState.name}
        onChange={(e) => dispatch({ type: 'SET_NAME', payload: e.target.value })}
        placeholder="Name"
      />
      <input
        value={formState.email}
        onChange={(e) => dispatch({ type: 'SET_EMAIL', payload: e.target.value })}
        placeholder="Email"
      />
      <input
        value={formState.password}
        onChange={(e) => dispatch({ type: 'SET_PASSWORD', payload: e.target.value })}
        placeholder="Password"
      />
    </>
  );
}
ログイン後にコピー

ここで、useReducer はすべての状態更新を 1 つの関数に集中させ、複数の useState 呼び出しよりも管理が容易になります。

useReducer を選択する場合:

  • 複数のサブ値またはアクションを含む複雑な状態ロジックを処理します。
  • 状態遷移が明確なアクションベースのフロー (SET、ADD、REMOVE など) に従う場合。

代わりに useContext を使用する必要がありますか?

状態が多くのコンポーネント間で共有されている場合、支柱の穴あけはすぐに悪夢になる可能性があります。そこで useContext が登場します。これは、props を複数のレベルに渡さずに状態を共有するのに役立ちます。

状況に応じた例:

ショッピング カートを作成していると想像してください。アプリのさまざまな部分 (ヘッダー、チェックアウト ページ、カート プレビューなど) でカートの状態 (追加されたアイテム、合計価格など) にアクセスできるようにする必要があります。

const CartContext = React.createContext();

function CartProvider({ children }) {
  const [cart, setCart] = useState([]);

  return (
    <CartContext.Provider value={{ cart, setCart }}>
      {children}
    </CartContext.Provider>
  );
}

function Header() {
  const { cart } = React.useContext(CartContext);
  return <div>Items in cart: {cart.length}</div>;
}

function App() {
  return (
    <CartProvider>
      <Header />
      {/* Other components */}
    </CartProvider>
  );
}
ログイン後にコピー

このシナリオでは、useContext により、props を手動で渡すことなく、カートの状態を必要とするコンポーネントでカートの状態を利用できるようになります。

useContext を選択する場合:

  • 深くネストされたコンポーネント間で状態を共有します。
  • 一般的にアクセスされるグローバル データ (ユーザー認証、テーマなど) のプロップ ドリルを回避します。

バランスの取れたアプローチ

useState は優れた出発点ですが、React のエコシステムは、コードを簡素化しパフォーマンスを向上させる useRef、useReducer、useContext などの他の強力なツールを提供します。デフォルトで useState に到達する代わりに、いくつかの重要な質問を自問してください。

  • この状態では再レンダリングをトリガーする必要がありますか? (そうでない場合は、useRef を検討してください)
  • 私の状態ロジックは useState に対して複雑になりすぎていますか? (Reducerを使ってみてください)
  • あまりにも多くのコンポーネントを介して props を渡しているのでしょうか? (useContext を調べてください)

ジョブに適したツールを選択することで、より効率的で保守しやすく、推論が容易な React コンポーネントを作成できます。

それで、次回デフォルトで useState を使用していることに気づいたら、少しの間立ち止まってください。もしかしたら、もっと良い対処方法があるかもしれません!

以上がすべてに「useState」が本当に必要ですか?代替案の検討の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート