Estou tendo problemas com um formulário React e gerenciando o estado corretamente. Eu tenho um campo de entrada de tempo em um formulário (em um modal). O valor inicial é definido como uma variável de estado getInitialState
e é passado de um componente pai. Isso por si só funciona bem.
O problema ocorre quando eu quero atualizar o valor padrão start_time através do componente pai. A atualização em si acontece no componente pai até setState start_time: new_time
. No entanto, no meu formulário, o valor padrão start_time nunca muda, pois é definido apenas uma vez getInitialState
.
Tentei usar componentWillUpdate
para forçar uma mudança de estado setState start_time: next_props.start_time
, o que realmente funcionou, mas me deu Uncaught RangeError: Maximum call stack size exceeded
erros.
Então, minha pergunta é: qual é a maneira correta de atualizar o estado nesse caso? Estou pensando nisso errado de alguma forma?
Código atual:
@ModalBody = React.createClass
getInitialState: ->
start_time: @props.start_time.format("HH:mm")
#works but takes long and causes:
#"Uncaught RangeError: Maximum call stack size exceeded"
componentWillUpdate: (next_props, next_state) ->
@setState(start_time: next_props.start_time.format("HH:mm"))
fieldChanged: (fieldName, event) ->
stateUpdate = {}
stateUpdate[fieldName] = event.target.value
@setState(stateUpdate)
render: ->
React.DOM.div
className: "modal-body"
React.DOM.form null,
React.createElement FormLabelInputField,
type: "time"
id: "start_time"
label_name: "Start Time"
value: @state.start_time
onChange: @fieldChanged.bind(null, "start_time”)
@FormLabelInputField = React.createClass
render: ->
React.DOM.div
className: "form-group"
React.DOM.label
htmlFor: @props.id
@props.label_name + ": "
React.DOM.input
className: "form-control"
type: @props.type
id: @props.id
value: @props.value
onChange: @props.onChange
[..]going to be deprecated in the future
Aparentemente, as coisas estão mudando ... getDerivedStateFromProps () agora é a função preferida.
(código acima por danburzo @ github)
fonte
null
se nada deve mudar tão logo após o seu caso, você deve ir comreturn null
getDerivedStateFromProps
ou mais memoization reactjs.org/blog/2018/06/07/…componentWillReceiveProps
está sendo preterido porque usá-lo "geralmente leva a erros e inconsistências".Se algo mudar de fora, considere redefinir completamente o componente filho
key
.Fornecer um
key
suporte ao componente filho garante que, sempre que o valor daskey
alterações for alterado externamente, esse componente seja renderizado novamente. Por exemplo,Em seu desempenho:
fonte
JSON.stringify(myObject)
derivar uma chave exclusiva do seu objeto.Há também componentDidUpdate disponível.
Assinatura da função:
Use isso como uma oportunidade para operar no DOM quando o componente tiver sido atualizado. Não é chamado na inicial
render
.Consulte Você provavelmente não precisa do artigo sobre o estado derivado , que descreve o antipadrão para ambos
componentDidUpdate
egetDerivedStateFromProps
. Eu achei muito útil.fonte
componentDidUpdate
porque é simples e é mais adequado para a maioria dos casos.A nova maneira de fazer ganchos é usar useEffect em vez de componentWillReceiveProps da maneira antiga:
torna-se o seguinte em um componente acionado por ganchos funcionais:
definimos o estado usando setState, usando useEffect, verificamos mudanças no suporte especificado e executamos a ação para atualizar o estado na alteração do suporte.
fonte
Você provavelmente não precisa de um estado derivado
1. Defina uma chave do pai
2. Use
getDerivedStateFromProps
/componentWillReceiveProps
Ao usar,
getDerivedStateFromProps
você pode redefinir qualquer parte do estado, mas parece um pouco problemático no momento (v16.7) !, consulte o link acima para saber o usofonte
Na documentação do react : https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
Desde a React 16, componentWillReceiveProps está obsoleto. Na documentação de reação, a abordagem recomendada neste caso é usar
ParentComponent
daModalBody
vontade possui ostart_time
estado. Esta não é minha abordagem preferida neste caso, pois acho que o modal deve possuir esse estado.start_time
do seu estadoModalBody
e o usariagetInitialState
exatamente como já fez. Para redefinir ostart_time
estado, basta alterar a chave doParentComponent
fonte
É claramente dos documentos deles:
Use: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization
fonte
Use Memoize
A derivação de estado do op é uma manipulação direta de adereços, sem a verdadeira derivação necessária. Em outras palavras, se você tem um suporte que pode ser utilizado ou transformado diretamente, não há necessidade de armazenar o suporte no estado .
Dado que o valor do estado de
start_time
é simplesmente o suportestart_time.format("HH:mm")
, as informações contidas no suporte já são suficientes para atualizar o componente.No entanto, se você quiser chamar apenas o formato em uma alteração de suporte, a maneira correta de fazer isso de acordo com a documentação mais recente seria através do Memoize: https://reactjs.org/blog/2018/06/07/you-probably-dont- need-derivated state.html # what-about-memoization
fonte
Eu acho que usar ref é seguro para mim, não precisa se preocupar com algum método acima.
fonte