Tengo un objeto externo (al componente) observable en el que quiero escuchar los cambios. Cuando el objeto se actualiza, emite eventos de cambio, y luego quiero volver a procesar el componente cuando se detecta cualquier cambio.
Con un nivel superior React.render
esto ha sido posible, pero dentro de un componente no funciona (lo cual tiene sentido ya que el render
método solo devuelve un objeto).
Aquí hay un ejemplo de código:
export default class MyComponent extends React.Component {
handleButtonClick() {
this.render();
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick.bind(this)}>
Click me
</button>
</div>
)
}
}
Al hacer clic internamente en el botón se llama this.render()
, pero eso no es lo que realmente hace que se produzca la representación (puede ver esto en acción porque el texto creado por {Math.random()}
no cambia). Sin embargo, si simplemente llamo en this.setState()
lugar de this.render()
, funciona bien.
Entonces, supongo que mi pregunta es: ¿los componentes React deben tener un estado para volver a reproducir? ¿Hay alguna forma de obligar al componente a actualizarse a demanda sin cambiar el estado?
this.forceUpdate()
es la solución correcta, mientras que el resto de todas las respuestas y varios comentarios están en contra del usoforceUpdate()
. ¿Entonces estará bien decir que la pregunta aún no obtuvo una solución / respuesta adecuada?Respuestas:
En su componente, puede llamar
this.forceUpdate()
para forzar una rendición.Documentación: https://facebook.github.io/react/docs/component-api.html
fuente
this.forceUpdate()
no es una muy buena solución para el problema de los solicitantes, es la respuesta correcta a la pregunta planteada en el título. Si bien generalmente debe evitarse, hay situaciones en las que forceUpdate es una buena solución.shouldComponentUpdate()
hacer que su solución sea inútil.forceUpdate
debe evitarse porque se desvía de una mentalidad React. Los documentos de React citan un ejemplo de cuándoforceUpdate
podría usarse:Sin embargo, me gustaría proponer la idea de que incluso con objetos profundamente anidados,
forceUpdate
es innecesario. Al usar una fuente de datos inmutable, los cambios de seguimiento se vuelven baratos; un cambio siempre dará como resultado un nuevo objeto, por lo que solo necesitamos verificar si la referencia al objeto ha cambiado. Puede usar la biblioteca Immutable JS para implementar objetos de datos inmutables en su aplicación.Cambiar la clave del elemento que desea volver a representar funcionará. Establezca la clave de apoyo en su elemento a través del estado y luego cuando desee actualizar el estado establecido para tener una nueva clave.
Luego se produce un cambio y restablece la clave
Quiero señalar que esto reemplazará el elemento en el que está cambiando la clave. Un ejemplo de dónde esto podría ser útil es cuando tiene un campo de entrada de archivo que desea restablecer después de cargar una imagen.
Si bien la verdadera respuesta a la pregunta del OP sería
forceUpdate()
que he encontrado esta solución útil en diferentes situaciones. También quiero señalar que si te encuentras usandoforceUpdate
es posible que desees revisar tu código y ver si hay otra forma de hacer las cosas.NOTA 1-9-2019:
Lo anterior (cambiando la clave) reemplazará completamente el elemento. Si te encuentras actualizando la clave para que los cambios sucedan, probablemente tengas un problema en otro lugar de tu código. Usar
Math.random()
in key recreará el elemento con cada render. NO recomendaría actualizar la clave de esta manera, ya que react utiliza la clave para determinar la mejor manera de volver a representar las cosas.fuente
key
. Primero, su intención no está clara. Un lector de su código tendrá que trabajar duro para comprender por qué lo está utilizando dekey
esta manera. En segundo lugar, esto no es más puro queforceUpdate
. Reacción "pura" significa que la presentación visual de su componente depende 100% de su estado, por lo que si cambia algún estado, se actualiza. Sin embargo, si tiene algunos objetos profundamente anidados (el escenario que losforceUpdate
documentos citan una razón para usarlo), entonces el uso loforceUpdate
deja claro. Tercero,Math.random()
es ... al azar. Teóricamente, podría generar el mismo número aleatorio.forceUpdate
es la forma de reaccionar de hacer esto.En realidad,
forceUpdate()
es la única solución correcta, ya quesetState()
podría no desencadenar una nueva representación si se implementa una lógica adicionalshouldComponentUpdate()
o simplemente cuando regresafalse
.forceUpdate ()
setState ()
forceUpdate()
puede ser llamado desde su componente porthis.forceUpdate()
Ganchos: ¿Cómo puedo forzar que el componente se vuelva a renderizar con ganchos en React?
Por cierto: ¿estás mutando o tus propiedades anidadas no se propagan?
fuente
this.state
exterior del constructor también debería arrojar un error. Podría no haberlo hecho en 2016; pero estoy bastante seguro de que lo hace ahora.Evité
forceUpdate
haciendo lo siguienteentonces, al hacer tal mejora de código, su componente será ÚNICO y se renderizará naturalmente
fuente
this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
Cuando desee que se comuniquen dos componentes React, que no están vinculados por una relación (padre-hijo), es recomendable utilizar Flux o arquitecturas similares.
Lo que desea hacer es escuchar los cambios del almacén de
componentes observables, que contiene el modelo y su interfaz, y guardar los datos que hacen que el render cambie comostate
enMyComponent
. Cuando la tienda envía los nuevos datos, cambia el estado de su componente, lo que activa automáticamente el renderizado.Normalmente debes tratar de evitar el uso
forceUpdate()
. De la documentación:fuente
react-redux
para asignar automáticamente el estado de la tienda a los accesorios del componente siempre que sea necesario en función de una función de mapeo que proporcione.forceUpdate
use ganchos o HOC elija
Usando ganchos o el patrón HOC (componente de orden superior) , puede tener actualizaciones automáticas cuando cambian sus tiendas. Este es un enfoque muy ligero sin un marco.
useStore Hooks forma de manejar las actualizaciones de la tienda
withStores HOC maneja las actualizaciones de la tienda
Clase SimpleStore
Cómo utilizar
En el caso de ganchos:
En el caso de HOC:
ASEGÚRESE de exportar sus tiendas como un singleton para obtener el beneficio del cambio global de esta manera:
Este enfoque es bastante simple y funciona para mí. También trabajo en equipos grandes y uso Redux y MobX y encuentro que también son buenos, pero solo un montón de repeticiones. Personalmente, me gusta mi propio enfoque porque siempre odié mucho código para algo que puede ser simple cuando lo necesitas.
fuente
this._data = {...this._data, ...newData}
.Las otras respuestas han tratado de ilustrar cómo podrías hacerlo, pero el punto es que no deberías . Incluso la solución hacky de cambiar la clave pierde el punto. El poder de React es ceder el control de administrar manualmente cuándo algo debería renderizarse, y en cambio solo preocuparse por cómo algo debería mapearse en las entradas. Luego suministrar flujo de entradas.
Si necesita forzar manualmente el re-renderizado, seguramente no está haciendo algo bien.
fuente
Podrías hacerlo de dos maneras:
1. Use el
forceUpdate()
método:Hay algunos problemas técnicos que pueden ocurrir al usar el
forceUpdate()
método. Un ejemplo es que ignora elshouldComponentUpdate()
método y volverá a representar la vista independientemente de sishouldComponentUpdate()
devuelve falso. Debido a esto, se debe evitar forceUpdate () cuando sea posible.2. Pasando this.state al
setState()
métodoLa siguiente línea de código supera el problema con el ejemplo anterior:
Realmente, todo lo que está haciendo es sobrescribir el estado actual con el estado actual que desencadena una nueva representación. Todavía no es necesariamente la mejor manera de hacer las cosas, pero supera algunos de los problemas técnicos que puede encontrar utilizando el método forceUpdate ().
fuente
this.setState(prevState => prevState);
Hay algunas formas de volver a procesar su componente:
La solución más simple es usar el método forceUpdate ():
Una solución más es crear una clave no utilizada en el estado (nonUsedKey) y llamar a la función setState con la actualización de esta nonUsedKey:
O reescribir todo el estado actual:
El cambio de utilería también proporciona la recuperación de componentes.
fuente
Para completar, también puede lograr esto en componentes funcionales:
O, como un gancho reutilizable:
Ver: https://stackoverflow.com/a/53215514/2692307
Tenga en cuenta que usar un mecanismo de actualización forzada sigue siendo una mala práctica, ya que va en contra de la mentalidad de reacción, por lo que aún debe evitarse si es posible.
fuente
Podemos usar this.forceUpdate () como se muestra a continuación.
La parte Element 'Math.random' en el DOM solo se actualiza incluso si usa setState para volver a representar el componente.
Todas las respuestas aquí son correctas, complementando la pregunta para la comprensión ... ya que sabemos que volver a representar un componente sin usar setState ({}) es usando forceUpdate ().
El código anterior se ejecuta con setState como se muestra a continuación.
fuente
Solo otra respuesta para respaldar la respuesta aceptada :-)
React desalienta el uso de
forceUpdate()
porque generalmente tienen un enfoque muy "esta es la única forma de hacerlo" hacia la programación funcional. Esto está bien en muchos casos, pero muchos desarrolladores de React vienen con un fondo OO, y con ese enfoque, está perfectamente bien escuchar un objeto observable.Y si lo hace, probablemente sepa que DEBE volver a renderizar cuando el "fuego" observable, y como tal, DEBE usarlo
forceUpdate()
y en realidad es un plus queshouldComponentUpdate()
NO está involucrado aquí.Herramientas como MobX, que adopta un enfoque OO, en realidad está haciendo esto debajo de la superficie (en realidad, MobX llama
render()
directamente)fuente
He encontrado que es mejor evitar forceUpdate (). Una forma de forzar el re-render es agregar dependencia de render () en una variable externa temporal y cambiar el valor de esa variable cuando sea necesario.
Aquí hay un ejemplo de código:
Llame this.forceChange () cuando necesite forzar el re-render.
fuente
ES6 - Incluyo un ejemplo que me fue útil:
En una "instrucción if corta" puede pasar una función vacía como esta:
Este parece ser el enfoque más corto.
fuente
forceUpdate();
el método funcionará pero es aconsejable usarsetState();
fuente
Para lograr lo que está describiendo, intente this.forceUpdate ().
fuente
Otra manera está llamando
setState
, y conserva el estado de:this.setState(prevState=>({...prevState}));
fuente
forceUpdate (), pero cada vez que escuché a alguien hablar sobre eso, se le ha seguido y nunca debe usar esto.
fuente
Puede usar forceUpdate () para ver más detalles ( forceUpdate () ).
fuente