ホームページ > ウェブフロントエンド > jsチュートリアル > React さん、派生状態について話さなければなりません!

React さん、派生状態について話さなければなりません!

Patricia Arquette
リリース: 2024-12-14 02:13:10
オリジナル
870 人が閲覧しました

React, we need to talk about Derived States!

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;
ログイン後にコピー

改善点は何ですか?

  1. filteredproducts に追加の状態はありません: filteredProducts の個別のリストは保存されなくなりました。代わりに、レンダリングごとに製品配列と searchQuery からフィルタリングされたリストを直接計算します。
  2. よりクリーンなコード: コンポーネントはよりシンプルになり、管理する状態が少なくなります。これにより、読みやすく、保守しやすくなります。
  3. パフォーマンスの向上 (一種): React は余分な状態変数を追跡する必要がありません。フィルタリングされたリストを既存のデータから直接導出するだけで、コードがより無駄がなく高速になります (React は更新を最適化しますが、状態の変更が少ない方が常に良いです)。

このアプローチは、派生状態を利用しており、フィルタリングされたデータの追加コピーを保存するのではなく、フィルタリングされた積が既存のデータから計算されます。


派生状態を使用しない場合

多くの場合、派生状態が最良の選択ですが、それがすべてに対する特効薬ではありません。コンポーネントがアプリケーションの複数の部分にわたって必要な複雑な計算や状態を処理している場合は、メモ化 を使用するか、派生した状態を上位レベルのコンポーネントまたはコンテキストに保存する方が良い場合があります。

ただし、単純なフィルタリング、並べ替え、またはその他の軽量な派生値の場合は、上記の例が頼りになるアプローチです。


結論

要約すると、React の派生状態とは、物事を DRY に保つ ことです。繰り返しはしないでください。同じデータの不必要なコピーを状態に保持するのではなく、既存の状態とプロパティに基づいてその場で値を計算します。これにより、コードがよりクリーンで効率的になり、保守が容易になります。したがって、次回 React でデータを複製したくなったら、他のソースから直接データを計算できるかどうかを検討してください。未来のあなたはあなたに感謝するでしょう!


以上がReact さん、派生状態について話さなければなりません!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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