Heim >Web-Frontend >js-Tutorial >ReactJS-Entwurfsmuster: Robuste und skalierbare Komponenten schreiben

ReactJS-Entwurfsmuster: Robuste und skalierbare Komponenten schreiben

王林
王林Original
2024-09-10 14:30:49450Durchsuche

ReactJS Design Patterns: Writing Robust and Scalable Components

Entwurfsmuster in ReactJS bieten standardisierte und bewährte Lösungen für häufige Probleme bei der Anwendungsentwicklung. Die Verwendung dieser Muster macht Ihren Code nicht nur lesbarer und wartbarer, sondern verbessert auch seine Skalierbarkeit und Robustheit. Lassen Sie uns in einige der beliebtesten ReactJS-Entwurfsmuster eintauchen, mit Beispielen, die ihre Verwendung veranschaulichen.

1. Container- und Präsentationskomponentenmuster

Das Container- und Präsentationsmuster unterteilt Komponenten in zwei Kategorien:

  • Präsentationskomponenten: Konzentrieren Sie sich auf das Aussehen der Dinge (UI).
  • Containerkomponenten: Konzentrieren Sie sich auf die Funktionsweise (Logik und Zustandsverwaltung).

Diese Trennung ermöglicht eine bessere Wiederverwendbarkeit, einfachere Tests und saubereren Code.

Beispiel: Präsentations- und Containerkomponenten

// Presentational Component: Displaying User List (UserList.js)
import React from 'react';

const UserList = ({ users }) => (
  <ul>
    {users.map((user) => (
      <li key={user.id}>{user.name}</li>
    ))}
  </ul>
);

export default UserList;
// Container Component: Fetching User Data (UserContainer.js)
import React, { useState, useEffect } from 'react';
import UserList from './UserList';

const UserContainer = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch('https://jsonplaceholder.typicode.com/users');
      const data = await response.json();
      setUsers(data);
    };
    fetchUsers();
  }, []);

  return <UserList users={users} />;
};

export default UserContainer;

Hier ist UserList eine Präsentationskomponente, die Benutzer als Requisiten empfängt, während UserContainer den Datenabruf und die Statusverwaltung übernimmt.

2. Muster für Komponenten höherer Ordnung (HOC)

Eine Higher-Order Component (HOC) ist eine Funktion, die eine Komponente als Argument verwendet und eine neue Komponente zurückgibt. HOCs werden häufig für übergreifende Anliegen wie Authentifizierung, Protokollierung oder Verbesserung des Komponentenverhaltens verwendet.

Beispiel: Erstellen eines HOC für die Autorisierung

// withAuthorization.js (HOC for Authorization)
import React from 'react';

const withAuthorization = (WrappedComponent) => {
  return class extends React.Component {
    componentDidMount() {
      if (!localStorage.getItem('authToken')) {
        // Redirect to login if not authenticated
        window.location.href = '/login';
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

export default withAuthorization;
// Dashboard.js (Component Wrapped with HOC)
import React from 'react';
import withAuthorization from './withAuthorization';

const Dashboard = () => <h1>Welcome to the Dashboard</h1>;

export default withAuthorization(Dashboard);

Indem Sie das Dashboard mit withAuthorization umschließen, stellen Sie sicher, dass nur authentifizierte Benutzer darauf zugreifen können.

3. Requisitenmuster rendern

Das Render Props-Muster beinhaltet die gemeinsame Nutzung von Code zwischen Komponenten mithilfe einer Requisite, deren Wert eine Funktion ist. Dieses Muster ist nützlich für das dynamische Rendering basierend auf bestimmten Bedingungen oder Zuständen.

Beispiel: Verwendung von Render-Requisiten für die Mausverfolgung

// MouseTracker.js (Component with Render Props)
import React, { useState } from 'react';

const MouseTracker = ({ render }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setPosition({ x: event.clientX, y: event.clientY });
  };

  return <div onMouseMove={handleMouseMove}>{render(position)}</div>;
};

export default MouseTracker;
// App.js (Using Render Props)
import React from 'react';
import MouseTracker from './MouseTracker';

const App = () => (
  <MouseTracker
    render={({ x, y }) => (
      <h1>
        Mouse position: ({x}, {y})
      </h1>
    )}
  />
);

export default App;

Die MouseTracker-Komponente verwendet eine Render-Requisite, um Mauspositionsdaten an jede Komponente zu übergeben, wodurch sie in hohem Maße wiederverwendbar ist.

4. Benutzerdefiniertes Hakenmuster

Benutzerdefinierte Hooks ermöglichen es Ihnen, zustandsbehaftete Logik über mehrere Komponenten hinweg zu kapseln und wiederzuverwenden. Dieses Muster fördert die Wiederverwendbarkeit von Code und eine saubere Trennung von Bedenken.

Beispiel: Erstellen eines benutzerdefinierten Hooks zum Abrufen von Daten

// useFetch.js (Custom Hook)
import { useState, useEffect } from 'react';

const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(url);
      const result = await response.json();
      setData(result);
      setLoading(false);
    };
    fetchData();
  }, [url]);

  return { data, loading };
};

export default useFetch;
// App.js (Using the Custom Hook)
import React from 'react';
import useFetch from './useFetch';

const App = () => {
  const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts');

  if (loading) return <div>Loading...</div>;

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
};

export default App;

Der benutzerdefinierte useFetch-Hook kapselt die Datenabruflogik, die in verschiedenen Komponenten wiederverwendet werden kann.

5. Muster zusammengesetzter Komponenten

Das Muster Zusammengesetzte Komponenten ermöglicht die Zusammenarbeit von Komponenten, um Zustand und Verhalten zu verwalten. Dieses Muster eignet sich zum Erstellen komplexer UI-Komponenten wie Tabs, Akkordeons oder Dropdowns.

Beispiel: Erstellen von Registerkarten mit zusammengesetzten Komponenten

// Tabs.js (Parent Component)
import React, { useState } from 'react';

const Tabs = ({ children }) => {
  const [activeIndex, setActiveIndex] = useState(0);

  return React.Children.map(children, (child, index) =>
    React.cloneElement(child, { isActive: index === activeIndex, setActiveIndex, index })
  );
};

const Tab = ({ children, isActive, setActiveIndex, index }) => (
  <button onClick={() => setActiveIndex(index)}>{children}</button>
);

const TabPanel = ({ children, isActive }) => (isActive ? <div>{children}</div> : null);

Tabs.Tab = Tab;
Tabs.TabPanel = TabPanel;

export default Tabs;
// App.js (Using Compound Components)
import React from 'react';
import Tabs from './Tabs';

const App = () => (
  <Tabs>
    <Tabs.Tab>Tab 1</Tabs.Tab>
    <Tabs.Tab>Tab 2</Tabs.Tab>
    <Tabs.TabPanel>Content for Tab 1</Tabs.TabPanel>
    <Tabs.TabPanel>Content for Tab 2</Tabs.TabPanel>
  </Tabs>
);

export default App;

Die Tabs-Komponente verwaltet den Status, während die Tab- und TabPanel-Komponenten zusammenarbeiten, um den Tab-Inhalt anzuzeigen.

6. Muster kontrollierter und unkontrollierter Komponenten

Kontrollierte Komponenten werden vollständig vom React-Status verwaltet, während unkontrollierte Komponenten für ihren Status auf das DOM angewiesen sind. Beide haben ihren Nutzen, aber kontrollierte Komponenten werden im Allgemeinen aus Gründen der Konsistenz und Wartbarkeit bevorzugt.

Beispiel: Kontrollierte vs. unkontrollierte Komponenten

// Controlled Component (TextInputControlled.js)
import React, { useState } from 'react';

const TextInputControlled = () => {
  const [value, setValue] = useState('');

  return (
    <input type="text" value={value} onChange={(e) => setValue(e.target.value)} />
  );
};

export default TextInputControlled;
// Uncontrolled Component (TextInputUncontrolled.js)
import React, { useRef } from 'react';

const TextInputUncontrolled = () => {
  const inputRef = useRef();

  const handleClick = () => {
    console.log(inputRef.current.value);
  };

  return (
    <>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>Log Input Value</button>
    </>
  );
};

export default TextInputUncontrolled;

In kontrollierten Komponenten steuert React den Formularstatus vollständig, während in unkontrollierten Komponenten der Status vom DOM selbst verwaltet wird.

7. Hooks Factory-Muster

Das Hooks Factory-Muster umfasst die Erstellung von Hooks, die dynamisch mehrere Zustände oder Verhaltensweisen generieren und verwalten und so eine flexible Möglichkeit zur Verwaltung komplexer Logik bieten.

Beispiel: Dynamisches Zustandsmanagement mit Hooks Factory

// useDynamicState.js (Hook Factory)
import { useState } from 'react';

const useDynamicState = (initialStates) => {
  const states = {};
  const setters = {};

  initialStates.forEach(([key, initialValue]) => {
    const [state, setState] = useState(initialValue);
    states[key] = state;
    setters[key] = setState;
  });

  return [states, setters];
};

export default useDynamicState;
// App.js (Using the Hooks Factory)
import React from 'react';
import useDynamicState from './useDynamicState';

const App = () => {
  const [states, setters] = useDynamicState([
    ['name', ''],
    ['age', 0],
  ]);

  return (
    <div>
      <input
        type="text"
        value={states.name}
        onChange={(e) => setters

.name(e.target.value)}
      />
      <input
        type="number"
        value={states.age}
        onChange={(e) => setters.age(parseInt(e.target.value))}
      />
      <p>Name: {states.name}</p>
      <p>Age: {states.age}</p>
    </div>
  );
};

export default App;

Diese Hook-Factory erstellt und verwaltet dynamisch mehrere Zustände und bietet so Flexibilität und saubereren Code.

Abschluss

Durch die Nutzung dieser Entwurfsmuster können Sie React-Anwendungen erstellen, die robuster, skalierbarer und wartbarer sind. Diese Muster helfen Ihnen, sauberen, wiederverwendbaren Code zu schreiben, der Best Practices entspricht, und stellen so sicher, dass Ihre Anwendung im Laufe der Zeit einfacher zu entwickeln und zu verwalten ist.

Möchten Sie tiefer in eines dieser Muster eintauchen oder andere Themen erkunden?

Das obige ist der detaillierte Inhalt vonReactJS-Entwurfsmuster: Robuste und skalierbare Komponenten schreiben. 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