Heim >Web-Frontend >js-Tutorial >Refactoring React: Das Chaos zähmen, eine Komponente nach der anderen

Refactoring React: Das Chaos zähmen, eine Komponente nach der anderen

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2025-01-15 07:35:43429Durchsuche

Refactoring React: Taming Chaos, One Component at a Time

Refactoring von React-Code ist, als würde man eine chaotische Küche in einen gut organisierten kulinarischen Zufluchtsort verwandeln. Es geht darum, die Struktur, Wartbarkeit und Leistung Ihrer App zu verbessern, ohne deren Funktionalität zu ändern. Egal, ob Sie mit aufgeblähten Komponenten oder einer verworrenen Zustandslogik zu kämpfen haben, ein gut geplanter Refactor verwandelt Ihre Codebasis in eine schlanke, effiziente Maschine.

Dieser Blog deckt gängige Refactoring-Szenarien auf, bietet umsetzbare Lösungen und versetzt Sie in die Lage, das wahre Potenzial Ihrer React-App auszuschöpfen.


Ich. Was ist Refactoring und warum ist es wichtig?

Refactoring verbessert die Struktur Ihres Codes, ohne seine Funktionalität zu ändern. Es geht nicht darum, Fehler zu beheben oder Funktionen hinzuzufügen – es geht darum, Ihren Code für Menschen und Maschinen gleichermaßen zu verbessern.

Warum Refactor?

  1. Lesbarkeit: Das Debuggen von Code um 3 Uhr morgens wird viel einfacher, wenn er sich wie ein guter Roman und nicht wie ein kryptisches Rätsel liest.
  2. Wartbarkeit: Eine saubere Codebasis spart Stunden Onboarding-Zeit und beschleunigt Aktualisierungen.
  3. Leistung: Saubererer Code führt häufig zu schnelleren Ladezeiten und einem reibungsloseren Benutzererlebnis.

? Profi-Tipp: Vermeiden Sie vorzeitige Optimierung. Refaktorieren Sie, wenn ein klarer Bedarf besteht, z. B. zur Verbesserung der Entwicklererfahrung oder zur Behebung langsamer Renderings.


II. Code-Gerüche aufspüren

Code-Gerüche sind subtile Signale für Ineffizienz oder Komplexität. Es handelt sich nicht um Fehler, aber sie weisen auf Bereiche hin, die verbessert werden müssen.

Häufige React-Code-Gerüche

  1. Aufgedunsene Komponenten
    • Problem: Eine einzelne Komponente übernimmt zu viele Aufgaben, wie das Abrufen von Daten, das Rendern und die Verarbeitung von Ereignissen.
   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>
     );
   }
  • Lösung: Teilen Sie es in kleinere, fokussierte Komponenten auf.
   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. Propellerbohren
    • Problem: Requisiten werden durch mehrere Schichten von Komponenten geleitet.
   <App>
     <ProductList product={product} />
   </App>
  • Lösung 1: Zusammensetzung verwenden.
   <ProductList>
     <ProductItem product={product} />
   </ProductList>
  • Lösung 2: Kontext verwenden.
   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. Verschachtelte ternäre Hölle
    • Problem: Komplexes bedingtes Rendering mit verschachtelten Ternärdateien.
   return condition1 ? a : condition2 ? b : condition3 ? c : d;
  • Lösung: Refactoring mithilfe von Hilfsfunktionen oder Switch-Anweisungen.
   function renderContent(condition) {
     switch (condition) {
       case 1: return a;
       case 2: return b;
       case 3: return c;
       default: return d;
     }
   }

   return renderContent(condition);
  1. Doppelte Logik
    • Problem: Wiederholen der gleichen Logik über alle Komponenten hinweg.
   function calculateTotal(cart) {
     return cart.reduce((total, item) => total + item.price, 0);
   }
  • Lösung: Verschieben Sie gemeinsam genutzte Logik in wiederverwendbare Dienstprogramme oder benutzerdefinierte Hooks.
   function calculateTotalPrice(cart) {
     return cart.reduce((total, item) => total + item.price, 0);
   }

   function useTotalPrice(cart) {
     return useMemo(() => calculateTotalPrice(cart), [cart]);
   }
  1. Übermäßiger Zustand
    • Problem: Abgeleiteten Zustand direkt verwalten.
   const [isLoggedIn, setIsLoggedIn] = useState(user !== null);
  • Lösung: Verwenden Sie stattdessen den abgeleiteten Zustand.
   const isLoggedIn = !!user; // Converts 'user' to boolean

III. Vereinfachte Zustandsverwaltung

Staatsmanagement ist wichtig, kann aber schnell chaotisch werden. So vereinfachen Sie es:

Abgeleiteter Zustand: Berechnen, nicht speichern

  • Problem:Redundanter Zustand wird gespeichert.
  • Lösung: Berechnen Sie abgeleitete Werte direkt aus der Quelle.
  const [cartItems, setCartItems] = useState([]);
  const totalPrice = cartItems.reduce((total, item) => total + item.price, 0);

Verwenden Sie useReducer für den komplexen Zustand

  • Problem:Mehrere voneinander abhängige Zustände.
  • Lösung: Verwenden Sie 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);

Staatliche Colocation

  • Problem:Globaler Status wird für lokale Daten verwendet.
  • Lösung: Verschieben Sie den Zustand näher an die Stelle, an der er benötigt wird.
  // 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. Refactoring-Komponenten

Komponenten sollten eine Aufgabe erfüllen und zwar gut. Zum Beispiel:

Ein Auftrag pro Komponente

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

V. Leistungsoptimierung

React Profiler

Verwenden Sie den Profiler, um Engpässe zu identifizieren. Greifen Sie in den Entwicklertools unter „Profiler“ darauf zu.

Auswendiglernen

Kostenintensive Berechnungen optimieren:

   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>
     );
   }

Hinweis: Vermeiden Sie übermäßiges Auswendiglernen für häufig aktualisierte Abhängigkeiten.


VI. Refactoring für Testbarkeit

Benutzerzentrierte Tests schreiben:

   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. Letzte Handgriffe für die Wartbarkeit

  1. Nach Funktion organisieren:
   <App>
     <ProductList product={product} />
   </App>
  1. Absolute Importe verwenden:
   <ProductList>
     <ProductItem product={product} />
   </ProductList>

VIII. Spickzettel

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.
Kategorie
Tipp Code-Smells Aufgeblähte Komponenten aufteilen; Vermeiden Sie Stützenbohrungen. Staatsverwaltung Abgeleiteten Zustand verwenden; Colocate-Status. Leistung Profiler verwenden; Kontextwerte optimieren. Testen Testverhalten, keine Implementierungsdetails.

Das obige ist der detaillierte Inhalt vonRefactoring React: Das Chaos zähmen, eine Komponente nach der anderen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn