Tengo un componente de función y quiero forzarlo a volver a renderizar.
¿Como lo puedo hacer?
Como no hay una instancia de this , no puedo llamar a this.forceUpdate() .
Usando ganchos de reacción, ahora puede llamar a useState() en su componente de función.
useState() devolverá una matriz de 2 cosas:
Actualizar el valor por su setter obligará a su componente de función a volver a renderizar ,
al igual que lo hace forceUpdate :
import React, { useState } from 'react'; //create your forceUpdate hook function useForceUpdate(){ const [value, setValue] = useState(0); // integer state return () => setValue(value => value + 1); // update the state to force render } 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 usa una función de gancho 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.
En una versión anterior de esta respuesta, el fragmento usaba un valor booleano y lo alternaba en 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 sucedió 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 setter de useState ( setValue aquí), React compara el estado anterior con el nuevo y lo procesa solo si el estado es diferente.
Actualizar reaccionar v16.8 (versión del 16 de febrero de 2019)
Desde que se lanzó React 16.8 con ganchos , los componentes de función ahora tienen la capacidad de mantener un state persistente. Con esa habilidad ahora puedes imitar un 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 reconsiderarse y, en la mayoría de los casos , cuando necesita forzar una actualización, probablemente esté haciendo algo mal.
Antes de reaccionar 16.8.0
No, no puede, los componentes de la función State-Less son solo functions normales que devuelven jsx , no tiene acceso a los métodos del ciclo de vida de React ya que no se está extendiendo desde React.Component .
Piense en el componente de función como la parte del método de render de los componentes de la clase.
Las preguntas frecuentes oficiales ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate ) ahora recomiendan esta forma si realmente necesita hacerlo:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0); function handleClick() { forceUpdate(); }