Ich habe 2 React-Komponenten, die einen Status teilen müssen, React-Router zeigt Komponente A, die einige Eingaben entgegennimmt und zu ihrem Status hinzufügt. Nachdem der Status erfolgreich aktualisiert wurde, möchte ich zu Komponente B umleiten, wo der Benutzer hinzufügt einige weitere Eingaben und Aktualisierungen desselben Zustands wie Komponente A, um ein Objekt mit Eingaben von A und B zu erstellen, bevor ich eine Post-Anforderung an meine API sende, um die Daten von Komponente A und B zu speichern. Wie kann ich dies erreichen, gibt es a Möglichkeit, React-Router zu verwenden, oder muss ich eine Eltern-/Kind-Beziehung zwischen den Komponenten einrichten?
Wie stellt man einen gemeinsamen Zustand zwischen zwei Reaktionskomponenten her?
Der Abhängigkeitstyp zwischen den Komponenten definiert den besten Ansatz.
Redux ist beispielsweise eine großartige Option, wenn Sie einen zentralen Speicher planen. Es sind jedoch auch andere Vorgehensweisen möglich:
-
Eltern zu Kind
- Requisiten
- Instanzmethoden
-
Kind zu Eltern
- Callback-Funktionen
- Ereignissprudeln
-
Geschwister zu Geschwister
- Übergeordnete Komponente
-
Beliebig zu Beliebig
- Beobachtermuster
- Globale Variablen
- Kontext
Bitte finden Sie mehr Ausführliche Informationen zu den einzelnen Ansätzen finden Sie hier
A. Vidor
Was Sie wollen, ist ein Objekt zu implementieren, das Ihren Zustand speichert, der mit Callback-Funktionen geändert werden kann. Sie können diese Funktionen dann an Ihre React-Komponenten übergeben.
Sie könnten beispielsweise einen Shop erstellen:
function Store(initialState = {}) {
this.state = initialState;
}
Store.prototype.mergeState = function(partialState) {
Object.assign(this.state, partialState);
};
var myStore = new Store();
ReactDOM.render(
<FirstComponent mergeState={myStore.mergeState.bind(myStore)} />,
firstElement
);
ReactDOM.render(
<SecondComponent mergeState={myStore.mergeState.bind(myStore)} />,
secondElement
);
Nun, sowohl die FirstComponent
und SecondComponent
Instanzen aufrufen können this.props.mergeState({ . . .})
Zustand demselben Geschäft zuzuweisen.
ich verlasse Store.prototype.getState
als Übung für den Leser.
Beachten Sie, dass Sie den Laden immer passieren können (myStore
) selbst zu den Komponenten; es fühlt sich einfach weniger reaktiv an, dies zu tun.
Hier sind weitere Unterlagen, die von Interesse sein könnten:
React Docs: „Kommunikation zwischen Komponenten“
Für die Kommunikation zwischen zwei Komponenten, die keine Eltern-Kind-Beziehung haben, können Sie Ihr eigenes globales Ereignissystem einrichten. Abonnieren Sie Ereignisse in componentDidMount(), kündigen Sie in componentWillUnmount() und rufen Sie setState() auf, wenn Sie ein Ereignis erhalten. Flussmuster ist eine der möglichen Möglichkeiten, dies zu arrangieren.
-
Reagieren Sie Anfänger hier: Ich bin neugierig, warum es unpraktisch ist, einen Elternteil künstlich in eine Kind-Kind-Beziehung einzuführen. Wäre der Ort, an dem eines der untergeordneten Elemente instanziiert wird, nicht auch ein Ort, der auf ein globales übergeordnetes Element verweisen und seinen Status teilen könnte, ähnlich wie Sie myStore teilen?
– Corey Alix
25. März 18 um 16:41 Uhr
-
@CoreyAlix Kannst du das Szenario, das du vorschlägst, etwas klarer darstellen? Was ist ein „globaler Elternteil“ und was bedeutet es für ein untergeordnetes Element, „auf einen globalen Elternteil zu verweisen“? Wenn Sie sich fragen, warum es nicht immer praktisch ist, den Zustand auf einem gemeinsamen Elternteil von zwei Knoten zu speichern, zerfällt dies in zwei getrennte Probleme: (1) Immer ein gemeinsames Elternteil finden oder erstellen; (2) Weitergabe der Informationen von einem gemeinsamen Elternteil an die relevanten Kinder auf eine Art und Weise, die keine Spaghetti ist.
– A. Vidor
25. März 18 um 22:07 Uhr
-
@CoreyAlix (2) ist der Kicker. Ich denke, es geht darum, das richtige Werkzeug für die Aufgabe auszuwählen: React-Komponenten sind sinnvoll, wenn die Knoten, die sie darstellen, und die Informationskanäle, die sie erstellen, der konzeptionellen Form der Anwendung folgen/vereinfachen. Wenn Sie anfangen, Ad-hoc-Knoten und -Eigenschaften als Reaktion auf neue Teile des gemeinsamen Zustands einzuführen, die im konzeptionellen Modell erscheinen, kann es zu einem Haarball werden! Aber wenn Sie nur fragen: “Warum ein Vanilla-Objekt anstelle einer React-Komponente eines “globalen Staatshalters”?”: Ich kann mir Situationen vorstellen, in denen beide Ansätze Vorteile haben.
– A. Vidor
25. März 18 um 22:12 Uhr
-
Ich habe mich gefragt, warum die Vanilla-Store-Lösung im Vergleich zu einer React-State-Komponente, ja. Der Reaktionszustand könnte verwendet werden, um an die Eigenschaften der Kinder zu binden und daher eine Eltern-> Kind-Bindung einzurichten. Eine der Eigenschaften könnte der Eltern-/Zustandssetzer selbst sein, wie in Ihrer vorgeschlagenen Lösung, der es den Kindern ermöglicht, den “globalen” Zustand festzulegen, und die gebundenen Eigenschaften beider Kinder werden aktualisiert. Ich behaupte nicht, dass ich es besser weiß, ich bin neugierig, warum eine Vanilla-Lösung sinnvoller ist?
– Corey Alix
26. März 18 um 0:09 Uhr
-
Dieser Referenzlink leitet woanders weiter.
– Schaschwatt
27. Dezember 18 um 08:03 Uhr
Der einfachste Weg, einen gemeinsam genutzten Zustand zwischen mehreren Komponenten zu verwenden, ohne den Code Ihrer Anwendung in ein Zustandsverwaltungssystem umzuschreiben, ist use-between
Haken.
Versuchen Sie dieses Beispiel in codesandbox
import React, { useState } from "react";
import { useBetween } from "use-between";
// Make a custom hook with your future shared state
const useFormState = () => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
return {
username, setUsername, email, setEmail
};
};
// Make a custom hook for sharing your form state between any components
const useSharedFormState = () => useBetween(useFormState);
const ComponentA = () => {
// Use the shared hook!
const { username, setUsername } = useSharedFormState();
return (
<p>
Username: <input value={username} onChange={(ev) => setUsername(ev.target.value)} />
</p>
);
};
const ComponentB = () => {
// Use the shared hook!
const { email, setEmail } = useSharedFormState();
return (
<p>
Email: <input value={email} onChange={(ev) => setEmail(ev.target.value)} />
</p>
);
};
const ComponentC = () => {
// Use shared hook!
const { email, username } = useSharedFormState();
return (
<p>
Username: {username} <br />
Email: {email}
</p>
);
};
export const App = () => (
<>
<ComponentA />
<ComponentB />
<ComponentC />
</>
);
- Zunächst erstellen wir
useFormState
benutzerdefinierte Haken als Quelle für unseren Zustand. - Im nächsten Schritt erstellen wir
useSharedFormState
Haken, der verwendetuseBetween
Haken hinein. Dieser Hook kann in jeder Komponente verwendet werden, die den freigegebenen Status lesen oder aktualisieren kann! - Und der letzte Schritt ist die Verwendung
useSharedFormState
in unseren Komponenten.
useBetween
ist eine Möglichkeit, einen beliebigen Haken zu nennen. Damit wird der Zustand aber nicht in der React-Komponente gespeichert. Für denselben Hook ist das Ergebnis des Aufrufs dasselbe. So können wir einen Hook in verschiedenen Komponenten aufrufen und gemeinsam an einem Zustand arbeiten. Beim Aktualisieren des freigegebenen Zustands wird jede Komponente, die ihn verwendet, ebenfalls aktualisiert.
Entweder Sie können eine Eltern-Kind-Beziehung einrichten, dann können Sie Daten als Requisiten an untergeordnete Komponenten übergeben.
Andernfalls, wenn Sie eine Interaktion zwischen 2 Komponenten erstellen möchten, die nicht mit beiden (Elternteil/Kind) verwandt sind, können Sie entweder auschecken Fluss oder noch besser reduzieren.
Ich würde sagen, Sie sollten mit Redux gehen.Sehen Sie hier warum
Makan
Sie können benutzerdefinierte React-Hooks erstellen, um a state
zwischen den Komponenten habe ich einen gemacht Hier. Sie können es durch Herunterladen verwenden use-linked-state.js
Datei.
Nach dem Import useStateGateway
Hook, deklarieren Sie ein Gateway in der übergeordneten Komponente und übergeben Sie es an Ihre untergeordneten Komponenten
import {useStateGateway} from "use-linked-state";
const myGateway = useStateGateway({partA:null, partB:null});
return (
<>
<ComponentA gateway={myGateway}>
<ComponentB gateway={myGateway}>
<ComponentPost gateWay={myGateway}>
</>
)
Dann haben Sie Zugriff auf den gemeinsamen Zustand zwischen diesen drei Komponenten durch einen benutzerdefinierten useLinkedState-Hook
import { useLinkedState } from "use-linked-state";
export default function ComponentA({gateway}){
const [state, setState] = useLinkedState(gateway);
<your logic>
}
In deiner Logik ComponentA
und ComponentB
für ihren Anteil am gemeinsamen Objekt verantwortlich wären {partA:"filled by ComponentA", partB:"filled by componentB"}
. Endlich ComponentPost
poste das Ergebnis ggf partA
und partB
des gemeinsam genutzten Objekts gültig waren.
Auf diese Weise können Sie Komponenten zusammenstellen und Verbindungen zwischen ihnen herstellen, um miteinander zu kommunizieren.
.
Schau mal rein reduzieren.
– Mario Tacke
11. August 16 um 16:00 Uhr
Oft wird der Reaktionszustand durch Flux / Redux oder so verwaltet. Ich persönlich mag Redux
– aw04
11. August 16 um 16:00 Uhr
Das macht sehr wenig Sinn. Es scheint, dass Sie entweder entscheiden würden, dass Sie Redux jetzt brauchen, oder auf die Aufgaben warten, die davon profitieren würden
– aw04
11. August 16 um 17:15 Uhr
Ich habe genau dieses Problem, aber es wird in Bezug auf den React-Router nicht gut beantwortet, soweit ich das beurteilen kann, wo Komponenten eher wie Konstruktoren sind. Ich gebe zu, ich weiß nichts über Redux, aber React-Router hat nicht wirklich Beispiele für die Integration.
– Stuart Watt
15. August 16 um 16:56 Uhr
Ich scheine spät hier zu sein, aber dieser Artikel hat mir sehr geholfen. medium.com/@ruthmpardee/… Es erklärt, wie Daten zwischen Komponenten in einer Eltern-Kind-Beziehung oder umgekehrt sowie zwischen Geschwistern weitergegeben werden.
– Delali
1. Juli 18 um 1:24 Uhr