Neuere Antwort mit einem Beispiel, das verwendet React.useState
Es wird empfohlen, den Status in der übergeordneten Komponente beizubehalten. Das übergeordnete Element muss Zugriff darauf haben, da es über zwei untergeordnete Komponenten hinweg verwaltet wird. Das Verschieben in den globalen Status, wie der von Redux verwaltete, wird aus demselben Grund nicht empfohlen, aus dem die globale Variable im Software-Engineering im Allgemeinen schlechter ist als die lokale .
Wenn sich der Status in der übergeordneten Komponente befindet, kann das Kind ihn mutieren, wenn das übergeordnete Element dem Kind valueund dem onChangeHandler Requisiten gibt (manchmal wird es als Wertverknüpfung oder Statusverknüpfungsmuster bezeichnet). So würden Sie es mit Haken machen:
function Parent() {
var [state, setState] = React.useState('initial input value');
return <>
<Child1 value={state} onChange={(v) => setState(v)} />
<Child2 value={state}>
</>
}
function Child1(props) {
return <input
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
}
function Child2(props) {
return <p>Content of the state {props.value}</p>
}
Die gesamte übergeordnete Komponente wird bei einer Eingabeänderung im untergeordneten Element erneut gerendert. Dies ist möglicherweise kein Problem, wenn die übergeordnete Komponente klein / schnell neu zu rendern ist. Die Leistung beim erneuten Rendern der übergeordneten Komponente kann im allgemeinen Fall weiterhin ein Problem sein (z. B. große Formulare). Dies ist das Problem in Ihrem Fall gelöst (siehe unten).
Das Statusverknüpfungsmuster und kein übergeordnetes erneutes Rendern lassen sich mithilfe der Drittanbieter-Bibliothek wie Hookstate einfacher implementieren - aufgeladen React.useState, um eine Vielzahl von Anwendungsfällen abzudecken, einschließlich Ihres. (Haftungsausschluss: Ich bin Autor des Projekts).
So würde es mit Hookstate aussehen. Child1wird die Eingabe ändern, Child2wird darauf reagieren. Parenthält den Status, wird aber nur bei Statusänderung nicht erneut gerendert Child1und Child2wird.
import { useStateLink } from '@hookstate/core';
function Parent() {
var state = useStateLink('initial input value');
return <>
<Child1 state={state} />
<Child2 state={state}>
</>
}
function Child1(props) {
// to avoid parent re-render use local state,
// could use `props.state` instead of `state` below instead
var state = useStateLink(props.state)
return <input
value={state.get()}
onChange={e => state.set(e.target.value)}
/>
}
function Child2(props) {
// to avoid parent re-render use local state,
// could use `props.state` instead of `state` below instead
var state = useStateLink(props.state)
return <p>Content of the state {state.get()}</p>
}
PS: Es gibt hier viele weitere Beispiele für ähnliche und kompliziertere Szenarien, einschließlich tief verschachtelter Daten, Statusvalidierung, globaler Status mit setStateHook usw. Es gibt auch eine vollständige Online-Beispielanwendung , die den Hookstate und die oben erläuterte Technik verwendet.