Gorakh Nath
Tengo un componente de función y quiero forzarlo a volver a renderizar.
¿Como lo puedo hacer?
Como no hay instancia this
No puedo llamar this.forceUpdate()
.
Yairopro
🎉 Ahora puedes, usando Ganchos de reacción
Usando ganchos de reacción, ahora puedes llamar useState()
en su componente de función.
useState()
devolverá una matriz de 2 cosas:
- Un valor, que representa el estado actual.
- Su colocador. Úselo para actualizar el valor.
Actualizar el valor por su setter obligará a su componente de función a volver a renderizar,
al igual que forceUpdate
lo hace:
import React, { useState } from 'react';
//create your forceUpdate hook
function useForceUpdate(){
const [value, setValue] = useState(0); // integer state
return () => setValue(value => value + 1); // update state to force render
// An function that increment 👆🏻 the previous state like here
// is better than directly setting `value + 1`
}
function MyComponent() {
// call your hook here
const forceUpdate = useForceUpdate();
return (
<div>
{/*Clicking on the button will force to re-render like force update does */}
<button onClick={forceUpdate}>
Click to re-render
</button>
</div>
);
}
Puede encontrar una demostración aquí.
El componente anterior utiliza una función de enlace personalizada (useForceUpdate
) que usa el gancho de estado de reacción useState
. Incrementa el valor del estado del componente y, por lo tanto, le dice a React que vuelva a renderizar el componente.
EDITAR
En una versión anterior de esta respuesta, el fragmento usaba un valor booleano y lo alternaba forceUpdate()
. Ahora que edité mi respuesta, el fragmento usa un número en lugar de un valor booleano.
Por qué ? (me preguntarías)
Porque una vez me pasó que mi forceUpdate()
fue llamado dos veces posteriormente desde 2 eventos diferentes y, por lo tanto, estaba restableciendo el valor booleano en su estado original, y el componente nunca se representó.
Esto se debe a que en el useState
colocador de (setValue
aquí), React
comparar el estado anterior con el nuevo, y renderizar sólo si el estado es diferente.
-
Nada en esa página tiene información sobre el uso de Hooks para llamar
forceUpdate
.– jdelman
21 de diciembre de 2018 a las 14:47
-
Por ahora, tienes razón, es mejor, porque, incluso los ganchos difíciles aún no se han lanzado, aún puedes usarlo en la versión beta. Pero una vez que se lanzan, no hay razón para que el componente de clase sea mejor. El uso de ganchos hace que el código sea más limpio que el componente de clase, como muestra el siguiente video en reactconf. De todos modos, la pregunta es si esto es posible. La respuesta ahora cambia de “No” a “Sí” debido a los ganchos. youtube.com/watch?v=wXLf18DsV-I
– Yairopro
22 de diciembre de 2018 a las 19:54
-
Hola @DanteTheSmith. Por “Nivel superior”, significa que los ganchos no deben llamarse desde dentro de una condición o bucle, como dijiste. Pero puedo decirte que puedes llamarlos desde dentro de otra función. Y eso significa crear un gancho personalizado. Dan Abramov, al presentar los ganchos de React en la conferencia de React, demuestra claramente que esta es la forma más limpia y mejor de compartir la lógica entre los componentes funcionales: youtu.be/dpw9EHDh2bM?t=2753
– Yairopro
10 mayo 2019 a las 12:53
-
@meandre Sí, definitivamente se compara. Estamos hablando de la
useState
gancho, no la clase’setState
que de hecho no hace una comparación (a menos que implemente el método shouldUpdate). Vea la misma demostración que publiqué, pero con un valor estático utilizado parasetState
no se renderiza de nuevo: codesandbox.io/s/determinado-rubin-8598l– Yairopro
15 de octubre de 2019 a las 13:18
-
un objeto vacío hará el mismo truco
– Muñeco de nieve
18 de noviembre de 2021 a las 10:58
Sagiv bg
Actualizar reaccionar v16.8 (versión del 16 de febrero de 2019)
Ya que reaccionar 16.8 lanzado con ganchoslos componentes de la función tienen la capacidad de mantener persistente state
. Con esa habilidad ahora puedes imitar a forceUpdate
:
function App() {
const [, updateState] = React.useState();
const forceUpdate = React.useCallback(() => updateState({}), []);
console.log("render");
return (
<div>
<button onClick={forceUpdate}>Force Render</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="root"/>
Tenga en cuenta que este enfoque debe ser reconsiderado y en mayoria de los casos cuando necesita forzar una actualización, probablemente esté haciendo algo mal.
Antes de reaccionar 16.8.0
No, no puedes, los componentes de la función State-Less son simplemente normales functions
que regresa jsx
no tiene acceso a los métodos del ciclo de vida de React ya que no se está extendiendo desde el React.Component
.
Piense en función-componente como el render
parte del método de los componentes de la clase.
-
eso no es forzando un re-render, eso es solo un render normal. cuando quieras fuerza renderizado, generalmente es un caso en el que desea ejecutar el método de renderizado cuando no fue diseñado para ejecutarse, por ejemplo, cuando no hay nuevos
props
ostate
cambios. usted no puede forzar la función render ya que no hayrender
función en componentes sin estado. los componentes sin estado noextends
React.Component
son simplemente funciones simples que devuelvenjsx
.– Sagiv bg
31 de octubre de 2017 a las 12:04
-
Apoyos para “cuando necesitas forzar una actualización, probablemente estés haciendo algo mal”.
– Metódico
30 de julio de 2019 a las 21:31
Gramotei
Preguntas frecuentes oficiales ahora recomienda esta manera si De Verdad necesito hacerlo:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
-
y puede acortar su código 7 bytes y no crear variables no utilizadas:
const [, forceUpdate] = useReducer(x => x + 1, 0);
– Konstantin Smolyanin
7 de mayo de 2020 a las 10:17
-
Más corto 👉
const forceUpdate = useReducer(x => x + 1, 0)[1]
– vsync
29 de agosto de 2022 a las 7:04
Abrahán
La forma más sencilla 👌
si desea forzar una nueva representación, agregue un estado ficticio que pueda cambiar para iniciar una nueva representación.
const [rerender, setRerender] = useState(false);
...
setRerender(!rerender); //whenever you want to re-render
Y esto asegurará una nueva renderización, y puedes llamar setRerender(!rerender)
donde quieras, cuando quieras 🙂
Usé una biblioteca de terceros llamada
usar-forzar-actualizar
para forzar la representación de mis componentes funcionales de reacción. Funcionó como el encanto. Simplemente use importar el paquete en su proyecto y utilícelo así.
import useForceUpdate from 'use-force-update';
const MyButton = () => {
const forceUpdate = useForceUpdate();
const handleClick = () => {
alert('I will re-render now.');
forceUpdate();
};
return <button onClick={handleClick} />;
};
-
Para ahorrarte un clic –
useForceUpdate
usosuseCallback
como se menciona en otras respuestas. Esta lib es solo una utilidad lib para ahorrarle algunas pulsaciones de teclas.– espera asincrónica
8 de febrero de 2020 a las 4:45
Alejandro Danilov
Mejor enfoque: no se vuelven a crear variables en exceso en cada renderizado:
const forceUpdateReducer = (i) => i + 1
export const useForceUpdate = () => {
const [, forceUpdate] = useReducer(forceUpdateReducer, 0)
return forceUpdate
}
Uso:
const forceUpdate = useForceUpdate()
forceUpdate()
-
Para ahorrarte un clic –
useForceUpdate
usosuseCallback
como se menciona en otras respuestas. Esta lib es solo una utilidad lib para ahorrarle algunas pulsaciones de teclas.– espera asincrónica
8 de febrero de 2020 a las 4:45
Arshal_d
Si ya tiene un estado dentro del componente de la función y no desea modificarlo y requiere una nueva representación, puede falsificar una actualización de estado que, a su vez, volverá a representar el componente.
const [items,setItems] = useState({
name:'Your Name',
status: 'Idle'
})
const reRender = () =>{
setItems((state) => [...state])
}
esto mantendrá el estado como estaba y hará reaccionar pensando que el estado ha sido actualizado
no, un componente sin estado no tiene estado. Usa una clase en su lugar
– Tratando de mejorar
15 de septiembre de 2017 a las 13:24
¿De verdad quieres decir “componente sin estado” y no “componente funcional”?
– Chris
15 de septiembre de 2017 a las 13:28
Para actualizar un componente sin estado, es necesario cambiar los accesorios pasados.
– hongo ántrax
15/09/2017 a las 20:17
además de los accesorios, puede usar hook useState, y los componentes se volverán a renderizar cuando cambie
–Hamid Shoja
16 de febrero de 2020 a las 4:17