Resposta mais recente com um exemplo, que usa React.useState
Manter o estado no componente pai é a maneira recomendada. O pai precisa ter acesso a ele, pois o gerencia em dois componentes filhos. Mover para o estado global, como o gerenciado pelo Redux, não é recomendado pelo mesmo motivo pelo qual a variável global é pior do que a local em geral na engenharia de software.
Quando o estado está no componente pai, o filho pode modificá-lo se o pai fornecer o filho value
e o onChange
manipulador em adereços (às vezes é chamado de link de valor ou padrão de link de estado ). Aqui está como você faria isso com 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 o componente pai será renderizado novamente na alteração de entrada no filho, o que pode não ser um problema se o componente pai for pequeno / rápido para ser renderizado novamente. O desempenho de re-renderização do componente pai ainda pode ser um problema no caso geral (por exemplo, formulários grandes). Este é o problema resolvido no seu caso (veja abaixo).
O padrão de link de estado e nenhuma re-renderização pai são mais fáceis de implementar usando a biblioteca de terceiros, como Hookstate - sobrecarregada React.useState
para cobrir diversos casos de uso, incluindo o seu. (Aviso: sou autor do projeto).
Aqui está como ficaria com o Hookstate. Child1
mudará a entrada, Child2
reagirá a ela. Parent
manterá o estado, mas não será renderizado novamente, somente Child1
e Child2
continuará.
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: existem muitos outros exemplos aqui, cobrindo cenários semelhantes e mais complicados, incluindo dados profundamente aninhados, validação de estado, estado global com setState
gancho, etc. Há também um aplicativo de amostra completo online , que usa o Hookstate e a técnica explicada acima.