Risposta più recente con un esempio, che utilizza React.useState
Mantenere lo stato nel componente padre è il modo consigliato. Il genitore deve avere accesso ad esso in quanto lo gestisce attraverso due componenti figlio. Spostarlo nello stato globale, come quello gestito da Redux, non è raccomandato per lo stesso motivo per cui la variabile globale è peggiore di quella locale in generale nell'ingegneria del software.
Quando lo stato è nel componente genitore, il figlio può mutarlo se il genitore fornisce il figlio value
e il onChange
gestore in oggetti di scena (a volte viene chiamato collegamento valore o modello collegamento stato ). Ecco come lo faresti con i ganci:
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>
}
L'intero componente genitore verrà sottoposto nuovamente al rendering in caso di modifica dell'input nel figlio, il che potrebbe non essere un problema se il componente genitore è di dimensioni ridotte / veloce per il nuovo rendering. Le prestazioni di nuovo rendering del componente padre possono comunque rappresentare un problema nel caso generale (ad esempio moduli di grandi dimensioni). Questo è un problema risolto nel tuo caso (vedi sotto).
Il modello di collegamento di stato e nessun nuovo rendering del genitore sono più facili da implementare utilizzando la libreria di terze parti, come Hookstate , sovralimentata React.useState
per coprire una varietà di casi d'uso, incluso il tuo. (Dichiarazione di non responsabilità: sono un autore del progetto).
Ecco come sarebbe con Hookstate. Child1
cambierà l'ingresso, Child2
reagirà ad esso. Parent
manterrà lo stato ma non eseguirà nuovamente il rendering al cambio di stato, solo Child1
e lo Child2
farà.
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: qui ci sono molti altri esempi che coprono scenari simili e più complicati, tra cui dati profondamente annidati, convalida dello stato, stato globale con setState
hook, ecc. Esiste anche un'applicazione di esempio online completa , che utilizza Hookstate e la tecnica spiegata sopra.