Wie erzwinge ich das Rendern einer funktionalen React-Komponente?

Lesezeit: 7 Minuten

Benutzeravatar von Gorakh Nath
Gorakh Nath

Ich habe eine Funktionskomponente und möchte sie zum erneuten Rendern zwingen.

Wie kann ich das tun?
Da es keine Instanz gibt thisIch kann nicht anrufen this.forceUpdate().

  • nein, eine zustandslose Komponente hat keinen Zustand. Verwenden Sie stattdessen eine Klasse

    – TryingToImprove

    15. September 2017 um 13:24 Uhr


  • Meinst du wirklich “staatenlose Komponente” und nicht “funktionale Komponente”?

    – Chris

    15. September 2017 um 13:28 Uhr


  • Um eine zustandslose Komponente zu aktualisieren, müssen die übergebenen Requisiten geändert werden.

    – Pilzanthrax

    15. September 2017 um 20:17 Uhr

  • Neben Requisiten können Sie Hook UseState verwenden, und Komponenten werden neu gerendert, wenn sie sich ändern

    – Hamid Shoja

    16. Februar 2020 um 4:17 Uhr

Benutzeravatar von Yairopro
Jairopro

🎉 Sie können jetzt mit Haken reagieren

Mit Reaktionshaken können Sie jetzt anrufen useState() in Ihrem Funktionsbaustein.

useState() wird ein Array von 2 Dingen zurückgeben:

  1. Ein Wert, der den aktuellen Status darstellt.
  2. Sein Setzer. Verwenden Sie es, um den Wert zu aktualisieren.

Das Aktualisieren des Werts durch seinen Setter zwingt Ihre Funktionskomponente zum erneuten Rendern,
so wie forceUpdate tut:

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
    // A function that increment 👆🏻 the previous state like here 
    // is better than directly setting `setValue(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>
    );
}

Eine Demo finden Sie hier.

Die obige Komponente verwendet eine benutzerdefinierte Hook-Funktion (useForceUpdate), die den React-State-Hook verwendet useState. Es erhöht den Zustandswert der Komponente und weist React somit an, die Komponente neu zu rendern.

BEARBEITEN

In einer alten Version dieser Antwort verwendete das Snippet einen booleschen Wert und schaltete ihn ein forceUpdate(). Nachdem ich meine Antwort bearbeitet habe, verwendet das Snippet eine Zahl anstelle eines booleschen Werts.

Warum ? (du würdest mich fragen)

Denn einmal ist es mir passiert, dass mein forceUpdate() wurde zweimal nacheinander von 2 verschiedenen Ereignissen aufgerufen, und somit wurde der boolesche Wert auf seinen ursprünglichen Zustand zurückgesetzt, und die Komponente wurde nie gerendert.

Dies liegt daran, dass in der useStates Setter (setValue hier), React Vergleichen Sie den vorherigen Zustand mit dem neuen, und nur rendern, wenn der Zustand unterschiedlich ist.

  • Nichts auf dieser Seite enthält Informationen zur Verwendung von Hooks zum Anrufen forceUpdate.

    – Jdelmann

    21. Dezember 2018 um 14:47 Uhr

  • Im Moment hast du Recht, es ist besser, denn selbst harte Hooks sind noch nicht veröffentlicht, du kannst es immer noch in der Beta verwenden. Aber sobald sie veröffentlicht sind, gibt es keinen Grund, warum die Klassenkomponente besser sein wird. Die Verwendung von Hooks macht den Code sauberer als die Klassenkomponente, wie das Video unten in der Reactconf zeigt. Jedenfalls ist die Frage, ob dies möglich ist. Die Antwort ändert sich nun aufgrund von Hooks von „Nein“ zu „Ja“. youtube.com/watch?v=wXLf18DsV-I

    – Jairopro

    22. Dezember 2018 um 19:54 Uhr


  • Hallo @DanteTheSmith. Mit “oberste Ebene” bedeutet dies, dass Hooks nicht aus einer Bedingung oder Schleife heraus aufgerufen werden dürfen, wie Sie sagten. Aber ich kann Ihnen sagen, dass Sie sie aus einer anderen Funktion heraus aufrufen können. Und das bedeutet, einen benutzerdefinierten Hook zu erstellen. Dan Abramov zeigt bei der Präsentation von React-Hooks in der React-Konf deutlich, dass dies der sauberste und beste Weg ist, Logik zwischen funktionalen Komponenten zu teilen: youtu.be/dpw9EHDh2bM?t=2753

    – Jairopro

    10. Mai 2019 um 12:53 Uhr

  • @meandre Ja, es ist definitiv vergleichbar. Wir sprechen über die useState Haken, nicht die Klasse’ setState was in der Tat keinen Vergleich macht (es sei denn, Sie implementieren die shouldUpdate-Methode). Sehen Sie sich die gleiche Demo an, die ich gepostet habe, aber mit einem statischen Wert, für den verwendet wird setStatees wird nicht erneut gerendert: codesandbox.io/s/determined-rubin-8598l

    – Jairopro

    15. Oktober 2019 um 13:18 Uhr


  • ein leeres Objekt macht den gleichen Trick

    – Schneemannzzz

    18. November 2021 um 10:58 Uhr

Benutzeravatar von Sagiv bg
Sagiv bg

Update reagieren v16.8 (Veröffentlichung vom 16. Februar 2019)

Seit reagieren 16.8 freigegeben mit Hakenhaben Funktionskomponenten die Fähigkeit, persistent zu bleiben state. Mit dieser Fähigkeit können Sie jetzt nachahmen 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"/>

Beachten Sie, dass dieser Ansatz überdacht und in Betracht gezogen werden sollte meiste Fälle Wenn Sie ein Update erzwingen müssen, machen Sie wahrscheinlich etwas falsch.


Vor der Reaktion 16.8.0

Nein, das können Sie nicht, zustandslose Funktionskomponenten sind ganz normal functions das kehrt zurück jsxhaben Sie keinen Zugriff auf die React-Lebenszyklusmethoden, da Sie nicht von erweitern React.Component.

Stellen Sie sich die Funktionskomponente als die vor render Methodenteil der Klassenkomponenten.

  • das ist nicht zwingen ein erneutes Rendern, das ist nur ein normales Rendern. wenn du willst Gewalt Beim Rendern ist dies normalerweise der Fall, wenn Sie die Rendermethode ausführen möchten, wenn sie nicht für die Ausführung vorgesehen ist, z. B. wenn es keine neuen gibt props oder state Änderungen. Sie kippen Erzwinge die Renderfunktion, da es keine gibt renderFunktion auf zustandslosen Komponenten. zustandslose Komponenten nicht extends React.Component Sie sind nur einfache Funktionen, die zurückgegeben werden jsx.

    – Sagiv bg

    31. Oktober 2017 um 12:04 Uhr


  • Requisiten für “Wenn Sie ein Update erzwingen müssen, machen Sie wahrscheinlich etwas falsch” – Ich wusste, dass dies der Fall war, aber dies veranlasste mich nur, einen weiteren guten Blick auf meinen useEffect-Hook zu werfen.

    – Methodiker

    30. Juli 2019 um 21:31 Uhr


Benutzeravatar von Gramotei
Gramotei

Offizielle FAQ jetzt empfiehlt diesen Weg, wenn Sie Ja wirklich muss es tun:

  const [ignored, forceUpdate] = useReducer(x => x + 1, 0);

  function handleClick() {
    forceUpdate();
  }

  • und Sie können Ihren Code 7 Bytes kürzer machen und keine unbenutzten Variablen erstellen: const [, forceUpdate] = useReducer(x => x + 1, 0);

    – Konstantin Smoljanin

    7. Mai 2020 um 10:17 Uhr

  • Kürzer 👉 const forceUpdate = useReducer(x => x + 1, 0)[1]

    – vsync

    29. August 2022 um 7:04 Uhr


Abrahams Benutzer-Avatar
Abraham

Einfachste Art 👌

Wenn Sie ein erneutes Rendern erzwingen möchten, fügen Sie einen Dummy-Status hinzu, den Sie ändern können, um ein erneutes Rendern einzuleiten.

const [rerender, setRerender] = useState(false);

...
setRerender(!rerender);     //whenever you want to re-render

Und dies sorgt für ein erneutes Rendern, und Sie können anrufen setRerender(!rerender) überall, wann immer du willst 🙂

Ich habe eine Bibliothek eines Drittanbieters namens
Use-Force-Update

um meine Reaktionsfunktionskomponenten zu rendern. Arbeitete wie Charme. Importieren Sie einfach das Paket in Ihr Projekt und verwenden Sie es so.

import useForceUpdate from 'use-force-update';

const MyButton = () => {

  const forceUpdate = useForceUpdate();

  const handleClick = () => {
    alert('I will re-render now.');
    forceUpdate();
  };

  return <button onClick={handleClick} />;
};

  • Um Ihnen einen Klick zu ersparen – useForceUpdate Verwendet useCallback wie in anderen Antworten erwähnt. Diese Bibliothek ist nur eine Hilfsbibliothek, um Ihnen einige Tastenanschläge zu ersparen.

    – asyncwait

    8. Februar 2020 um 4:45 Uhr

Benutzeravatar von Alexander Danilov
Alexander Danilow

Bester Ansatz – keine überflüssigen Variablen, die bei jedem Rendern neu erstellt werden:

const forceUpdateReducer = (i) => i + 1

export const useForceUpdate = () => {
  const [, forceUpdate] = useReducer(forceUpdateReducer, 0)
  return forceUpdate
}

Verwendung:

const forceUpdate = useForceUpdate()

forceUpdate()

  • Um Ihnen einen Klick zu ersparen – useForceUpdate Verwendet useCallback wie in anderen Antworten erwähnt. Diese Bibliothek ist nur eine Hilfsbibliothek, um Ihnen einige Tastenanschläge zu ersparen.

    – asyncwait

    8. Februar 2020 um 4:45 Uhr

Benutzeravatar von Arshal_d
Arschall_d

Wenn Sie bereits einen Status in der Funktionskomponente haben und ihn nicht ändern möchten und ein erneutes Rendern erfordern, können Sie eine Statusaktualisierung vortäuschen, die wiederum die Komponente neu rendern wird

const [items,setItems] = useState({
   name:'Your Name',
   status: 'Idle'
})
const reRender = () =>{
setItems((state) => [...state])
}

Dadurch bleibt der Zustand unverändert und die Reaktion lässt vermuten, dass der Zustand aktualisiert wurde

1439110cookie-checkWie erzwinge ich das Rendern einer funktionalen React-Komponente?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy