首頁 > web前端 > js教程 > 重構 React:馴服混亂,一次一個元件

重構 React:馴服混亂,一次一個元件

Mary-Kate Olsen
發布: 2025-01-15 07:35:43
原創
427 人瀏覽過

Refactoring React: Taming Chaos, One Component at a Time

重建 React 程式碼就像把一個混亂的廚房變成一個組織良好的烹飪天堂。它是關於在不改變應用程式功能的情況下改進應用程式的結構、可維護性和效能。無論您是在與臃腫的組件還是混亂的狀態邏輯作鬥爭,精心策劃的重構都會將您的程式碼庫轉變為流暢、高效的機器。

本部落格揭示了常見的重構場景,提供了可行的解決方案,並使您能夠釋放 React 應用程式的真正潛力。


我。什麼是重構以及為什麼它很重要?

重構可以在不改變程式碼功能的情況下改進程式碼的結構。這不是為了修復錯誤或添加功能,而是為了讓您的程式碼對人類和機器都更好。

為什麼要重構?

  1. 可讀性:當程式碼讀起來像一本好小說而不是一個神秘的謎題時,在凌晨 3 點調試程式碼會變得容易得多。
  2. 可維護性:乾淨的程式碼庫可以節省數小時的入門時間並加快更新速度。
  3. 效能:更簡潔的程式碼通常意味著更快的載入時間和更流暢的使用者體驗。

專業提示:避免過早最佳化。當有明確的需求時進行重構,例如改善開發人員體驗或解決緩慢的渲染問題。


二.嗅出程式碼味道

程式碼異味是低效率或複雜性的微妙訊號。它們不是錯誤,但它們表明了需要改進的地方。

常見的 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. 支柱鑽井
    • 問題: 透過多層元件傳遞 props。
   <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. 嵌套三元地獄
    • 問題: 使用巢狀三元組的複雜條件渲染。
   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
登入後複製

三.簡化狀態管理

狀態管理很重要,但很快就會變得混亂。以下是簡化方法:

派生狀態:計算,不儲存

  • 問題:儲存冗餘狀態。
  • 解:直接從來源計算派生值。
  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} />;
  }
登入後複製

四。重構組件

組件應該只做一項工作並且做得很好。例如:

每個組件一個作業

function MemberCard({ member }) {
  return (
    <div>
      <Summary member={member} />
      <SeeMore details={member.details} />
    </div>
  );
}
登入後複製

V.效能最佳化

反應分析器

使用分析器來辨識瓶頸。在“Profiler”下的開發者工具中存取它。

記憶

最佳化昂貴的計算:

   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>
登入後複製
登入後複製

八。備忘單

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:馴服混亂,一次一個元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板