Respuesta más reciente con un ejemplo, que utiliza React.useState
Mantener el estado en el componente principal es la forma recomendada. El padre debe tener acceso a él, ya que lo gestiona a través de dos componentes secundarios. No se recomienda moverlo al estado global, como el administrado por Redux, por la misma razón por la cual la variable global es peor que la local en general en ingeniería de software.
Cuando el estado está en el componente padre, el niño puede mutarlo si el padre le da al niño value
y al onChange
manejador en accesorios (a veces se llama enlace de valor o patrón de enlace de estado ). Así es como lo haría con ganchos:
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>
}
Todo el componente principal se volverá a representar en el cambio de entrada en el elemento secundario, lo que podría no ser un problema si el componente principal es pequeño / rápido de volver a representar. El rendimiento de representación del componente principal todavía puede ser un problema en el caso general (por ejemplo, formularios grandes). Este es un problema resuelto en su caso (ver más abajo).
El patrón de enlace de estado y la reproducción sin padre son más fáciles de implementar usando la biblioteca de terceros, como Hookstate , sobrealimentada React.useState
para cubrir una variedad de casos de uso, incluido el suyo. (Descargo de responsabilidad: soy un autor del proyecto).
Así es como se vería con Hookstate. Child1
cambiará la entrada, Child2
reaccionará a ella. Parent
mantendrá el estado pero no se volverá a procesar en el cambio de estado, solo Child1
y lo Child2
hará.
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>
}
PD: hay muchos más ejemplos aquí que cubren escenarios similares y más complicados, incluidos datos profundamente anidados, validación de estado, estado global con setState
gancho, etc. También hay una aplicación de muestra completa en línea , que utiliza el Hookstate y la técnica explicada anteriormente.