¿Cómo forzar un componente funcional de React para renderizar?

7 minutos de lectura

Avatar de usuario de Gorakh Nath
Gorakh Nath

Tengo un componente de función y quiero forzarlo a volver a renderizar.

¿Como lo puedo hacer?
Como no hay instancia thisNo puedo llamar this.forceUpdate().

  • 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

Avatar de usuario de Yairopro
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:

  1. Un valor, que representa el estado actual.
  2. 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 useStatecolocador 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 para setStateno 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

Avatar de usuario de Sagiv bg
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 jsxno 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 o state cambios. usted no puede forzar la función render ya que no hay renderfunción en componentes sin estado. los componentes sin estado no extends React.Component son simplemente funciones simples que devuelven jsx.

    – 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


Avatar de usuario de Gramotei
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


Avatar de usuario de Abraham
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 usos useCallback 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

Avatar de usuario de Alexander Danilov
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 usos useCallback 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

Avatar de usuario de Arshal_d
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

¿Ha sido útil esta solución?