Tengo problemas con un formulario React y con la administración adecuada del estado. Tengo un campo de entrada de tiempo en un formulario (en un modal). El valor inicial se establece como una variable de estado getInitialState
y se pasa desde un componente primario. Esto en sí mismo funciona bien.
El problema surge cuando quiero actualizar el valor predeterminado de start_time a través del componente principal. La actualización en sí ocurre en el componente principal a través de setState start_time: new_time
. Sin embargo, en mi forma, el valor predeterminado de start_time nunca cambia, ya que solo se define una vez getInitialState
.
He tratado de usar componentWillUpdate
para forzar un cambio de estado setState start_time: next_props.start_time
, lo que realmente funcionó, pero me dio Uncaught RangeError: Maximum call stack size exceeded
errores.
Entonces mi pregunta es, ¿cuál es la forma correcta de actualizar el estado en este caso? ¿Estoy pensando en esto mal de alguna manera?
Código actual:
@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 las cosas están cambiando ... getDerivedStateFromProps () es ahora la función preferida.
(código anterior por danburzo @ github)
fuente
null
si nada debería cambiar, así que justo después de su if, debe ir conreturn null
getDerivedStateFromProps
o la memorización reactjs.org/blog/2018/06/07/…componentWillReceiveProps
está en desuso porque su uso "a menudo genera errores e inconsistencias".Si algo cambia desde el exterior, considere restablecer el componente hijo por completo con
key
.Proporcionar un
key
accesorio al componente secundario asegura que siempre que el valor de loskey
cambios desde el exterior, este componente se vuelva a representar. P.ej,Sobre su rendimiento:
fuente
JSON.stringify(myObject)
para derivar una clave única de su objeto.También hay componentDidUpdate disponible.
Función firmante:
Use esto como una oportunidad para operar en el DOM cuando el componente se haya actualizado. No se llama en la inicial
render
.Vea que probablemente no necesite el artículo de estado derivado , que describe Anti-Pattern para ambos
componentDidUpdate
ygetDerivedStateFromProps
. Lo encontré muy útil.fuente
componentDidUpdate
porque es simple y es más adecuado para la mayoría de los casos.La nueva forma de hacer esto es usar useEffect en lugar de componentWillReceiveProps de la manera anterior:
se convierte en lo siguiente en un componente impulsado por ganchos funcionales:
configuramos el estado usando setState, usando useEffect, verificamos los cambios en el accesorio especificado y tomamos la acción para actualizar el estado al cambiar el accesorio.
fuente
Probablemente no necesite estado derivado
1. Establecer una clave del padre
2. Use
getDerivedStateFromProps
/componentWillReceiveProps
Al usarlo
getDerivedStateFromProps
, puede restablecer cualquier parte del estado, ¡pero parece un poco defectuoso en este momento (v16.7) !, vea el enlace de arriba para el usofuente
De la documentación de reacción: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
Desde React 16, componentWillReceiveProps está en desuso. De la documentación de reacción, el enfoque recomendado en este caso es el uso
ParentComponent
de laModalBody
voluntad posee elstart_time
estado. Este no es mi enfoque preferido en este caso, ya que creo que el modal debería ser el propietario de este estado.start_time
estadoModalBody
y lo usaríagetInitialState
tal como lo hizo anteriormente. Para restablecer elstart_time
estado, simplemente cambie la clave delParentComponent
fuente
Es bastante claro de sus documentos:
Uso: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization
fuente
Use Memoize
La derivación de estado de la operación es una manipulación directa de accesorios, sin necesidad de derivación verdadera. En otras palabras, si tiene un accesorio que se puede utilizar o transformar directamente, no es necesario almacenar el accesorio en estado .
Dado que el valor de estado de
start_time
es simplemente el accesoriostart_time.format("HH:mm")
, la información contenida en el accesorio ya es suficiente en sí misma para actualizar el componente.Sin embargo, si solo deseaba llamar al formato en un cambio de utilería, la forma correcta de hacerlo según la última documentación sería mediante Memoize: https://reactjs.org/blog/2018/06/07/you-probably-dont- need-derivado-estado.html # what-about-memoization
fuente
Creo que usar ref es seguro para mí, no necesito preocuparme por algún método anterior.
fuente