Zusammenfassung der drei Regeln für die React-Statusverwaltung

Zusammenfassung der drei Regeln für die React-Statusverwaltung

Vorwort

Der Status innerhalb einer React-Komponente besteht aus gekapselten Daten, die zwischen Rendering-Durchläufen bestehen bleiben. useState() ist ein React-Hook, der für die Verwaltung des Status innerhalb funktionaler Komponenten verantwortlich ist.

Ich liebe useState(), es macht die Statusverwaltung wirklich sehr einfach. Aber ich stoße oft auf ähnliche Probleme:

  • Soll ich den Zustand der Komponente in kleine Zustände aufteilen oder ihn als zusammengesetzten Zustand beibehalten?
  • Wenn die Statusverwaltung kompliziert wird, sollte ich sie aus der Komponente extrahieren? Was zu tun?
  • Wenn die Verwendung von useState() so einfach ist, wann wird dann useReducer() benötigt?

Dieser Artikel stellt drei einfache Regeln vor, die die oben genannten Fragen beantworten und Ihnen dabei helfen können, den Zustand Ihrer Komponenten zu gestalten.

Nr.1 Ein Fokus

Die erste Regel einer effektiven Staatsverwaltung lautet:

Machen Sie die Zustandsvariable für ein Problem verantwortlich.

Wenn eine Zustandsvariable für ein Anliegen verantwortlich gemacht wird, entspricht sie dem Single Responsibility Principle.

Sehen wir uns ein Beispiel für einen zusammengesetzten Zustand an, also einen Zustand, der mehrere Zustandswerte enthält.

const [Zustand, setzeZustand] = useState({
    an: wahr,
    Anzahl: 0
});

status.on // => true
Zustand.Anzahl // => 0

Der Status besteht aus einem einfachen JavaScript-Objekt mit den Eigenschaften „On“ und „Count“.

Die erste Eigenschaft, state.on, enthält einen Booleschen Wert, der einen Schalter angibt. Ebenso enthält „state.count“ eine Zahl, die einen Zähler darstellt, beispielsweise die Anzahl der Klicks des Benutzers auf eine Schaltfläche.

Nehmen wir dann an, Sie möchten den Zähler um 1 erhöhen:

// Zusammengesetzten Status aktualisieren
setzeBenutzer({
    ...Zustand,
    Anzahl: Status.Anzahl + 1
});

Sie müssen den gesamten Status zusammenhalten, um nur die Anzahl zu aktualisieren. Dies ist eine große Struktur, die nur zum Erhöhen eines Zählers aufgerufen wird. Dies liegt daran, dass die Statusvariable für zwei Dinge verantwortlich ist: den Schalter und den Zähler.

Die Lösung besteht darin, den zusammengesetzten Zustand in zwei atomare Zustände aufzuteilen und zu zählen:

const [ein, setOnOff] = useState(true);
const [Anzahl, Anzahl festlegen] = useState(0);

Die Zustandsvariable on ist lediglich für die Speicherung des Schalterzustandes zuständig. Auch hier ist die Variable count nur für den Zähler zuständig.

Versuchen wir nun, den Zähler zu aktualisieren:

setCount(Anzahl + 1);
// oder über einen Callback
setCount(Anzahl => Anzahl + 1);

Der Zählstand ist lediglich eine Zählung und lässt sich leicht nachvollziehen, aktualisieren und lesen.

Sie müssen nicht mehrere useState() aufrufen, um für jedes Anliegen Statusvariablen zu erstellen.

Beachten Sie jedoch, dass Ihre Komponente wahrscheinlich gegen das „Single Responsibility Principle“ verstößt, wenn Sie zu viele useState()-Variablen verwenden. Teilen Sie solche Komponenten einfach in kleinere auf.

Nr. 2 Extrahieren komplexer Zustandslogik

Extrahieren Sie komplexe Zustandslogik in benutzerdefinierte Hooks.

Ist es sinnvoll, komplexe Zustandsmanipulationen innerhalb von Komponenten zu belassen?

Die Antwort ergibt sich (wie so oft) aus den Grundlagen.

React-Hooks wurden erstellt, um Komponenten von komplexer Zustandsverwaltung und Nebenwirkungen zu isolieren. Da sich eine Komponente nur darum kümmern sollte, welche Elemente gerendert und welche Ereignis-Listener angehängt werden sollen, sollte die komplexe Statuslogik in einen benutzerdefinierten Hook extrahiert werden.

Stellen Sie sich eine Komponente vor, die eine Produktliste verwaltet. Benutzer können neue Produktnamen hinzufügen. Die Einschränkung besteht darin, dass Produktnamen eindeutig sein müssen.

Der erste Versuch bestand darin, den Setter für die Liste der Produktnamen direkt in der Komponente zu belassen:

Funktion ProdukteListe() {
    const [Namen, setze Namen] = useState([]);  
    const [neuerName, setzeNeuenName] = useState('');

    const map = name => <div>{name}</div>;

    const handleChange = Ereignis => setNewName(Ereignis.Ziel.Wert);
    const handleAdd = () => {    
        const s = neues Set([...Namen, neuerName]);    
        setNames([...s]); };
    zurückkehren (
        <div className="Produkte">
            {Namen.Map(Map)}
            <input type="text" onChange={handleChange} />
            <button onClick={handleAdd}>Hinzufügen</button>
        </div>
    );
}

Die Statusvariable „Namen“ enthält die Produktnamen. Wenn auf die Schaltfläche „Hinzufügen“ geklickt wird, wird der Ereignishandler „addNewProduct()“ aufgerufen.

Innerhalb von addNewProduct() wird ein Set-Objekt verwendet, um die Eindeutigkeit der Produktnamen sicherzustellen. Sollte sich die Komponente mit diesem Implementierungsdetail befassen? unnötig.

Es empfiehlt sich, komplexe Statussetter-Logik in einem benutzerdefinierten Hook zu isolieren. Lasst uns anfangen.

Neuer benutzerdefinierter Hook useUnique(), um jedes Element eindeutig zu machen:

// useUnique.js
Exportfunktion useUnique(initial) {
    const [Elemente, Elemente festlegen] = useState(initial);
    const add = neuesItem => {
        const uniqueItems = [...neues Set([...items, neuesItem])];
        setItems(einzigartigeItems);
    };
    zurückgeben [Elemente, hinzufügen];
};

Durch das Extrahieren der benutzerdefinierten Statusverwaltung in einen Hook wird die Komponente ProductsList leichter:

importiere { useUnique } von './useUnique';

Funktion ProdukteListe() {
  const [Namen, hinzufügen] = useUnique([]); const [neuerName, setzeNeuenName] = useState('');

  const map = name => <div>{name}</div>;

  const handleChange = Ereignis => setNewName(e.target.value);
  const handleAdd = () => add(neuerName);
  zurückkehren (
    <div className="Produkte">
      {Namen.Map(Map)}
      <input type="text" onChange={handleChange} />
      <button onClick={handleAdd}>Hinzufügen</button>
    </div>
  );
}

const [names, addName] = useUnique([]) aktiviert benutzerdefinierte Hooks. Die Komponente wird nicht mehr durch eine komplexe Zustandsverwaltung behindert.

Wenn Sie der Liste einen neuen Namen hinzufügen möchten, rufen Sie einfach add('Neuer Produktname') auf.

Die wichtigsten Vorteile der Extraktion einer komplexen Statusverwaltung in benutzerdefinierte Hooks sind:

  • Diese Komponente enthält nicht mehr die Details der Zustandsverwaltung
  • Benutzerdefinierte Haken können wiederverwendet werden
  • Benutzerdefinierte Hooks können problemlos isoliert getestet werden

Nr. 3 Extrahieren mehrerer Statusvorgänge

Extrahieren Sie mehrere Statusoperationen in Reduzierer.

Um mit dem Beispiel „ProductsList“ fortzufahren, wollen wir einen „Löschvorgang“ einführen, der einen Produktnamen aus der Liste entfernt.

Jetzt müssen Sie zwei Vorgänge codieren: Hinzufügen und Entfernen von Produkten. Durch die Handhabung dieser Vorgänge können Sie einen Vereinfacher erstellen und Ihre Komponente von der Statusverwaltungslogik befreien.

Auch dieser Ansatz passt zur Idee von Hooks: Extrahieren einer komplexen Zustandsverwaltung aus Komponenten.

Hier ist eine Implementierung eines Reduzierers, der Produkte hinzufügt und entfernt:

Funktion uniqueReducer(Zustand, Aktion) {
    Schalter (Aktion.Typ) {
        Fall 'Hinzufügen':
            zurückgeben [...neues Set([...Status, Aktionsname])];
        Fall 'löschen':
            Statusfilter zurückgeben (Name => Name === Aktionsname);
        Standard:
            neuen Fehler werfen();
    }
}

Sie können dann uniqueReducer() auf Ihre Produktliste anwenden, indem Sie den useReducer()-Hook von React aufrufen:

Funktion ProdukteListe() {
    const [Namen, Versand] = useReducer (uniqueReducer, []);
    const [neuerName, setzeNeuenName] = useState('');

    const handleChange = Ereignis => setNewName(Ereignis.Ziel.Wert);

    const handleAdd = () => dispatch({ Typ: 'add', Name: neuerName });
    const map = Name => {
        const delete = () => dispatch({ Typ: 'löschen', Name });    
        zurückkehren (
            <div>
                {Name}
                <button onClick={delete}>Löschen</button>
            </div>
        );
    }

    zurückkehren (
        <div className="Produkte">
            {Namen.Map(Map)}
            <input type="text" onChange={handleChange} />
            <button onClick={handleAdd}>Hinzufügen</button>
        </div>
    );
}

const [Namen, Dispatch] = useReducer(uniqueReducer, []) aktiviert uniqueReducer. „names“ ist die Statusvariable, die die Namen der Produkte enthält, und „dispatch“ ist die Funktion, die mit dem Aktionsobjekt aufgerufen wird.

Wenn auf die Schaltfläche „Hinzufügen“ geklickt wird, ruft der Handler „dispatch({ type: 'add', name: newName })“ auf. Das Aussenden einer Add-Aktion bewirkt, dass der Reducer uniqueReducer dem Status einen neuen Produktnamen hinzufügt.

Wenn auf die Schaltfläche „Löschen“ geklickt wird, ruft der Handler auf die gleiche Weise „dispatch({ type: 'delete', name })“ auf. Der Entfernungsvorgang entfernt einen Produktnamen aus dem Namensstatus.

Interessanterweise sind Reduzierer ein Sonderfall des Befehlsmusters.

Zusammenfassen

Zustandsvariablen sollten sich nur auf einen Punkt konzentrieren.

Wenn der Status eine komplexe Aktualisierungslogik hat, extrahieren Sie diese Logik aus der Komponente in einen benutzerdefinierten Hook.

Wenn der Status mehrere Aktionen erfordert, verwenden Sie entsprechend einen Reduzierer, um diese Aktionen zu kombinieren.

Welche Regeln Sie auch immer verwenden, der Status sollte so einfach und entkoppelt wie möglich gehalten werden. Komponenten sollten sich nicht mit den Details von Statusaktualisierungen befassen: Sie sollten Teil benutzerdefinierter Hooks oder Reducer sein.

Mit diesen drei einfachen Regeln ist Ihre Zustandslogik leicht zu verstehen, zu warten und zu testen.

Damit ist dieser Artikel zu den drei Regeln der React-Statusverwaltung abgeschlossen. Weitere Inhalte zur React-Statusverwaltung finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Untersuchung der drei zugrunde liegenden Mechanismen der globalen Statusverwaltung von React
  • Beispiel für die Verwendung der Statusverwaltungsmethode von Vue in React
  • Interpretation und Verwendung verschiedener React-State-Manager

<<:  Kodierungsprobleme und -lösungen, wenn MySQL zwei Tabellen verknüpft

>>:  So erstellen Sie geplante Aufgaben mit dem Crond-Tool in Linux

Artikel empfehlen

So lösen Sie das Zeichensatzproblem bei der Anmeldung bei Linux

Zeichensatzfehler treten immer auf Gebietsschema:...

Mysql NULL verursachte die Grube

Verwenden von NULL in Vergleichsoperatoren mysql&...

JS, CSS und HTML zur Implementierung der Registrierungsseite

Eine mit HTML und CSS implementierte Registrierun...

So konvertieren Sie MySQL horizontal in vertikal und vertikal in horizontal

Daten initialisieren Tabelle löschen, wenn `test_...

Zwei Möglichkeiten zur Implementierung von Square Div mit CSS

Ziel: Erstelle ein Quadrat, dessen Seitenlänge gl...

CocosCreator - modulares Lernskript

Modulares Cocos Creator-Skript Mit Cocos Creator ...

Miniprogramm zur Implementierung des kompletten Einkaufswagens

Das Miniprogramm implementiert einen vollständige...

Detaillierte Erklärung, wie MySQL Phantom-Lesevorgänge löst

1. Was ist Phantomlesen? Wenn bei einer Transakti...

Klassifizierung der Farbeigenschaften von Webseiten

Klassifizierung der Farbeigenschaften Jede Farbe ...

Detaillierte Erläuterung des Prozessmanagements im Linux-System

Inhaltsverzeichnis 1. Das Konzept von Prozess und...

Gründe und Lösungen für das Versagen des React-Ereignisdrosselungseffekts

Inhaltsverzeichnis Das Problem hierbei ist: Lösun...