Eu tenho a seguinte estrutura:
FormEditor
- contém vários FieldEditor
FieldEditor
- edita um campo do formulário e salva vários valores sobre ele no seu estado
Quando um botão é clicado no FormEditor, desejo poder coletar informações sobre os campos de todos os FieldEditor
componentes, informações que estão em seu estado e tê-las no FormEditor.
Eu considerei armazenar as informações sobre os campos fora do FieldEditor
estado de e, em FormEditor
vez disso, colocá-las no estado de estado. No entanto, isso exigiria FormEditor
ouvir cada um de seus FieldEditor
componentes à medida que eles mudam e armazenam suas informações em seu estado.
Não posso simplesmente acessar o estado das crianças? É ideal?
javascript
reactjs
Moshe Revah
fonte
fonte
FieldEditor
s separadamente, é bom salvar o estado delesFormEditor
. Se for esse o caso, suasFieldEditor
instâncias serão renderizadas com base noprops
passado pelo editor de formulários, e não pelostate
. Uma maneira mais complexa, porém flexível, seria criar um serializador que atravesse qualquer filho do contêiner e encontre todas asFormEditor
instâncias entre eles e os serialize em um objeto JSON. O objeto JSON pode opcionalmente ser aninhado (mais de um nível) com base nos níveis de aninhamento das instâncias no editor de formulários.Respostas:
Se você já possui o manipulador onChange para os FieldEditors individuais, não vejo por que você não pode simplesmente mover o estado para o componente FormEditor e apenas passar um retorno de chamada para os FieldEditors que atualizarão o estado pai. Isso me parece uma maneira mais reativa de fazer isso.
Talvez algo assim:
Original - versão pré-ganchos:
Mostrar snippet de código
fonte
myAPI.SaveStuff(this.state);
. Se você elaborar um pouco mais, talvez eu possa lhe dar uma resposta melhor :)Antes de entrar em detalhes sobre como você pode acessar o estado de um componente filho, leia a resposta de Markus-ipse sobre uma solução melhor para lidar com esse cenário específico.
Se você realmente deseja acessar o estado dos filhos de um componente, pode atribuir uma propriedade chamada
ref
a cada filho. Agora, existem duas maneiras de implementar referências: UsandoReact.createRef()
e referências de retorno de chamada.Usando
React.createRef()
Atualmente, é a maneira recomendada de usar referências a partir do React 16.3 (consulte a documentação para obter mais informações). Se você estiver usando uma versão anterior, veja abaixo as referências de retorno de chamada.
Você precisará criar uma nova referência no construtor do componente pai e depois atribuí-la a um filho por meio do
ref
atributoPara acessar esse tipo de referência, você precisará usar:
Isso retornará uma instância do componente montado para que você possa usar
currentFieldEditor1.state
para acessar o estado.Apenas uma observação rápida para dizer que, se você usar essas referências em um nó DOM em vez de em um componente (por exemplo
<div ref={this.divRef} />
),this.divRef.current
retornará o elemento DOM subjacente em vez de uma instância de componente.Referências de retorno de chamada
Essa propriedade utiliza uma função de retorno de chamada que recebe uma referência ao componente conectado. Esse retorno de chamada é executado imediatamente após o componente ser montado ou desmontado.
Por exemplo:
Nestes exemplos, a referência é armazenada no componente pai. Para chamar esse componente no seu código, você pode usar:
e depois use
this.fieldEditor1.state
para obter o estado.Uma coisa a observar, verifique se o componente filho foi renderizado antes de tentar acessá-lo ^ _ ^
Como acima, se você usar essas referências em um nó DOM em vez de em um componente (por exemplo
<div ref={(divRef) => {this.myDiv = divRef;}} />
),this.divRef
retornará o elemento DOM subjacente em vez de uma instância do componente.Outras informações
Se você quiser ler mais sobre a propriedade ref do React, confira esta página no Facebook.
Leia a seção "Não use demais referências ", que diz que você não deve usar a criança
state
para "fazer as coisas acontecerem".Espero que isso ajude ^ _ ^
Edit: Adicionado
React.createRef()
método para criar refs. Código ES5 removido.fonte
this.refs.yourComponentNameHere
. Achei útil mudar o estado por meio de funções. Exemplo:this.refs.textInputField.clearInput();
props
estate
. No entanto, eles não devem ser sua abstração essencial para o fluxo de dados através de seu aplicativo. Por padrão, use o fluxo de dados Reativo e salveref
s para casos de uso inerentemente não reativos.connected
componente Redux ?Em 2020, muitos de vocês virão aqui procurando uma solução semelhante, mas com Hooks (Eles são ótimos!) E com as abordagens mais recentes em termos de limpeza e sintaxe do código.
Portanto, como as respostas anteriores declararam, a melhor abordagem para esse tipo de problema é manter o estado fora do componente filho
fieldEditor
. Você poderia fazer isso de várias maneiras.O mais "complexo" é o contexto (estado) global que pai e filho podem acessar e modificar. É uma ótima solução quando os componentes são muito profundos na hierarquia da árvore e, portanto, é caro enviar adereços em cada nível.
Nesse caso, acho que não vale a pena, e uma abordagem mais simples nos trará os resultados que queremos, apenas usando os poderosos
React.useState()
.Abordagem com o gancho React.useState (), muito mais simples do que com os componentes da classe
Como dito, lidaremos com as alterações e armazenaremos os dados de nosso componente filho
fieldEditor
em nossos paisfieldForm
. Para fazer isso, enviaremos uma referência à função que tratará e aplicará as alterações nofieldForm
estado, você pode fazer isso com:Observe que
React.useState({})
retornará uma matriz com a posição 0 sendo o valor especificado na chamada (neste caso, objeto vazio) e a posição 1 sendo a referência à função que modifica o valor.Agora, com o componente filho
FieldEditor
, você nem precisa criar uma função com uma instrução de retorno, uma constante enxuta com uma função de seta serve!E pronto, nada mais, com apenas esses dois componentes funcionais do lodo, temos nosso objetivo final de "acessar" o
FieldEditor
valor filho e exibi-lo em nossos pais.Você pode verificar a resposta aceita de 5 anos atrás e ver como Hooks tornou o código do React mais enxuto (Por muito!).
Espero que minha resposta ajude você a aprender e entender mais sobre Hooks, e se você quiser verificar um exemplo de trabalho, aqui está .
fonte
Agora você pode acessar o estado do InputField, filho do FormEditor.
Basicamente, sempre que há uma alteração no estado do campo de entrada (filho), estamos obtendo o valor do objeto de evento e passando esse valor para o Pai onde o estado no Pai está definido.
Ao clicar no botão, estamos apenas imprimindo o estado dos campos de Entrada.
O ponto principal aqui é que estamos usando os adereços para obter o ID / valor do campo de entrada e também para chamar as funções definidas como atributos no campo de entrada enquanto geramos os campos filho reutilizáveis de entrada.
fonte
Como as respostas anteriores disseram, tente mover o estado para um componente superior e modifique o estado através de retornos de chamada passados para seus filhos.
Caso você realmente precise acessar um estado filho declarado como um componente funcional (ganchos), pode declarar uma referência no componente pai e passá-la como um atributo ref à criança, mas precisa usar React.forwardRef e, em seguida, o gancho useImperativeHandle para declarar uma função que você pode chamar no componente pai.
Veja o seguinte exemplo:
Então, você poderá obter myState no componente Pai chamando:
myRef.current.getMyState();
fonte