Ich habe eine Funktionskomponente und möchte sie zum erneuten Rendern zwingen.
Wie kann ich das tun?
Da es keine Instanz gibt this
Ich kann nicht anrufen this.forceUpdate()
.
Gorakh Nath
Ich habe eine Funktionskomponente und möchte sie zum erneuten Rendern zwingen.
Wie kann ich das tun?
Da es keine Instanz gibt this
Ich kann nicht anrufen this.forceUpdate()
.
Jairopro
Mit Reaktionshaken können Sie jetzt anrufen useState()
in Ihrem Funktionsbaustein.
useState()
wird ein Array von 2 Dingen zurückgeben:
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>
);
}
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.
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 useState
s 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 setState
es 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
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 jsx
haben 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 render
Funktion 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
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
Abraham
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
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
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
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