ホームページ >ウェブフロントエンド >jsチュートリアル >React のリファクタリング: 一度に 1 つのコンポーネントを使用して混沌を制御する

React のリファクタリング: 一度に 1 つのコンポーネントを使用して混沌を制御する

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2025-01-15 07:35:43429ブラウズ

Refactoring React: Taming Chaos, One Component at a Time

React コードをリファクタリングすることは、混沌としたキッチンを整理整頓された料理天国に変えるようなものです。アプリの機能を変更せずに、アプリの構造、保守性、パフォーマンスを向上させることが重要です。肥大化したコンポーネントや複雑な状態ロジックと戦っている場合でも、綿密に計画されたリファクタリングにより、コードベースが洗練された効率的なマシンに変換されます。

このブログでは、一般的なリファクタリング シナリオを明らかにし、実用的なソリューションを提供し、React アプリの真の可能性を引き出すための手段を提供します。


私。リファクタリングとは何ですか?なぜ重要ですか?

リファクタリングは、コードの機能を変更せずにコードの構造を改善します。それはバグを修正したり機能を追加したりすることではなく、コードを人間とマシンの両方にとってより良いものにすることです。

なぜリファクタリングするのですか?

  1. 可読性: 難解なパズルではなく優れた小説のように読めると、午前 3 時のコードのデバッグがはるかに簡単になります。
  2. 保守性: クリーンなコードベースにより、何時間ものオンボーディング時間が節約され、更新が高速化されます。
  3. パフォーマンス: コードがよりクリーンになると、多くの場合、読み込み時間が短縮され、ユーザー エクスペリエンスがよりスムーズになります。

? プロのヒント: 時期尚早な最適化は避けてください。開発者エクスペリエンスの向上やレンダリングの遅さへの対処など、明確なニーズがある場合はリファクタリングを行ってください。


II.コードの匂いを嗅ぎ分ける

コードの匂いは、非効率または複雑さの微妙なシグナルです。これらはエラーではありませんが、改善が必要な領域を示しています。

よくある React コードの匂い

  1. 肥大化したコンポーネント
    • 問題: データのフェッチ、レンダリング、イベントの処理など、単一のコンポーネントがあまりにも多くの役割を処理します。
   function ProductPage() {
     const [data, setData] = useState([]);
     useEffect(() => fetchData(), []);
     const handleAddToCart = () => { ... };
     return (
       <div>
         {data.map(item => <ProductItem key={item.id} item={item} />)}
         <button onClick={handleAddToCart}>Add to Cart</button>
       </div>
     );
   }
  • 解決策: より小さな、焦点を絞ったコンポーネントに分割します。
   function ProductPage() {
     return (
       <div>
         <ProductList />
         <CartButton />
       </div>
     );
   }

   function ProductList() {
     const [data, setData] = useState([]);
     useEffect(() => fetchData(), []);
     return data.map(item => <ProductItem key={item.id} item={item} />);
   }

   function CartButton() {
     const handleAddToCart = () => { ... };
     return <button onClick={handleAddToCart}>Add to Cart</button>;
   }
  1. プロップドリル
    • 問題: コンポーネントの複数のレイヤーにプロップを渡す。
   <App>
     <ProductList product={product} />
   </App>
  • 解決策 1: 合成を使用します。
   <ProductList>
     <ProductItem product={product} />
   </ProductList>
  • 解決策 2: コンテキストを使用します。
   const ProductContext = React.createContext();

   function App() {
     const [product, setProduct] = useState({ id: 1, name: 'Example Product' }); // Example state
     return (
       <ProductContext.Provider value={product}>
         <ProductList />
       </ProductContext.Provider>
     );
   }

   function ProductList() {
     const product = useContext(ProductContext);
     return <ProductItem product={product} />;
   }
  1. 入れ子になった三元地獄
    • 問題: ネストされた 3 項を使用した複雑な条件付きレンダリング。
   return condition1 ? a : condition2 ? b : condition3 ? c : d;
  • 解決策: ヘルパー関数または switch ステートメントを使用してリファクタリングします。
   function renderContent(condition) {
     switch (condition) {
       case 1: return a;
       case 2: return b;
       case 3: return c;
       default: return d;
     }
   }

   return renderContent(condition);
  1. ロジックの重複
    • 問題: コンポーネント間で同じロジックが繰り返されます。
   function calculateTotal(cart) {
     return cart.reduce((total, item) => total + item.price, 0);
   }
  • 解決策: 共有ロジックを再利用可能なユーティリティまたはカスタム フックに移動します。
   function calculateTotalPrice(cart) {
     return cart.reduce((total, item) => total + item.price, 0);
   }

   function useTotalPrice(cart) {
     return useMemo(() => calculateTotalPrice(cart), [cart]);
   }
  1. 過剰な状態
    • 問題: 派生状態を直接管理します。
   const [isLoggedIn, setIsLoggedIn] = useState(user !== null);
  • 解決策: 代わりに派生状態を使用します。
   const isLoggedIn = !!user; // Converts 'user' to boolean

III.状態管理の簡素化

状態管理は不可欠ですが、すぐに混乱してしまう可能性があります。簡略化する方法は次のとおりです:

派生状態: 計算し、保存しない

  • 問題: 冗長状態を保存しています。
  • 解決策: 派生値をソースから直接計算します。
  const [cartItems, setCartItems] = useState([]);
  const totalPrice = cartItems.reduce((total, item) => total + item.price, 0);

複雑な状態に useReducer を使用する

  • 問題: 複数の相互依存状態。
  • 解決策: useReducer を使用します。
  const initialState = { count: 0 };
  function reducer(state, action) {
    switch (action.type) {
      case 'increment': return { count: state.count + 1 };
      default: return state;
    }
  }
  const [state, dispatch] = useReducer(reducer, initialState);

状態コロケーション

  • 問題: ローカル データに使用されるグローバル状態。
  • 解決策: 状態を必要な場所に近づけます。
  // Before:
  function App() {
    const [filter, setFilter] = useState('');
    return <ProductList filter={filter} onFilterChange={setFilter} />;
  }

  // After:
  function ProductList() {
    const [filter, setFilter] = useState('');
    return <FilterInput value={filter} onChange={setFilter} />;
  }

IV.コンポーネントのリファクタリング

コンポーネントは 1 つのジョブを適切に実行する必要があります。例:

コンポーネントごとに 1 つのジョブ

function MemberCard({ member }) {
  return (
    <div>
      <Summary member={member} />
      <SeeMore details={member.details} />
    </div>
  );
}

V.パフォーマンスの最適化

React プロファイラー

プロファイラーを使用してボトルネックを特定します。開発者ツールの「プロファイラー」でアクセスします。

メモ化

コストのかかる計算を最適化します:

   function ProductPage() {
     const [data, setData] = useState([]);
     useEffect(() => fetchData(), []);
     const handleAddToCart = () => { ... };
     return (
       <div>
         {data.map(item => <ProductItem key={item.id} item={item} />)}
         <button onClick={handleAddToCart}>Add to Cart</button>
       </div>
     );
   }

注: 頻繁に更新される依存関係に対してメモ化を過度に使用しないでください。


VI.テスト容易性のためのリファクタリング

ユーザー中心のテストを作成します:

   function ProductPage() {
     return (
       <div>
         <ProductList />
         <CartButton />
       </div>
     );
   }

   function ProductList() {
     const [data, setData] = useState([]);
     useEffect(() => fetchData(), []);
     return data.map(item => <ProductItem key={item.id} item={item} />);
   }

   function CartButton() {
     const handleAddToCart = () => { ... };
     return <button onClick={handleAddToCart}>Add to Cart</button>;
   }

VII.保守性の最終調整

  1. 機能ごとに整理:
   <App>
     <ProductList product={product} />
   </App>
  1. 絶対インポートを使用します:
   <ProductList>
     <ProductItem product={product} />
   </ProductList>

VIII.チートシート

Category Tip
Code Smells Split bloated components; avoid prop drilling.
State Management Use derived state; colocate state.
Performance Use Profiler; optimize Context values.
Testing Test behavior, not implementation details.
カテゴリ
ヒント コードの匂い 肥大化したコンポーネントを分割します。小道具の穴あけは避けてください。 状態管理 派生状態を使用します。状態を併置します。 パフォーマンス プロファイラーを使用します。コンテキスト値を最適化します。 テスト中 実装の詳細ではなく、動作をテストします。

以上がReact のリファクタリング: 一度に 1 つのコンポーネントを使用して混沌を制御するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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