Ich habe eine Funktionskomponente und möchte sie zum erneuten Rendern zwingen.
Wie kann ich das machen?
Da es keine Instanz gibt this
, kann ich nicht anrufen this.forceUpdate()
.
javascript
reactjs
Gorakh Nath
quelle
quelle
Antworten:
🎉 Sie können jetzt React Hooks verwenden
Mit React Hooks können Sie jetzt
useState()
Ihre Funktionskomponente aufrufen .useState()
gibt ein Array von 2 Dingen zurück:1. Ein Wert, der den aktuellen Status darstellt.
2. Sein Setter. Verwenden Sie diese Option, um den Wert zu aktualisieren.
Den Wert durch seine Setter Aktualisierung wird Ihre Funktion Komponente zwingen, wieder zu machen ,
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); // 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> ); }
Eine Demo finden Sie hier .
Die obige Komponente verwendet eine benutzerdefinierte Hook-Funktion (
useForceUpdate
), die einen booleschen Status-Hook (useState
) verwendet. Es schaltet den booleschen Status um und weist React an, die Renderfunktion erneut auszuführen.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 my
forceUpdate()
von zwei verschiedenen Ereignissen zweimal aufgerufen wurde und somit den booleschen Wert auf seinen ursprünglichen Zustand zurückgesetzt hat und die Komponente nie gerendert wurde.Denn im
useState
Setter des S (setValue
hier)React
vergleichen Sie den vorherigen Status mit dem neuen und rendern nur, wenn der Status anders ist.quelle
forceUpdate
.useState
Hook, nicht über die Klasse ',setState
die in der Tat keinen Vergleich durchführt (es sei denn, Sie implementieren die shouldUpdate-Methode). Siehe die gleiche Demo, die ich gepostet habe, aber mit einem statischen Wert, der für verwendet wirdsetState
, wird sie nicht erneut gerendertUpdate reagieren v16.8 (16. Februar 2019 Veröffentlichung)
Seit React 16.8 mit Hooks freigegeben wurde , können Funktionskomponenten nun dauerhaft gehalten werden
state
. Mit dieser Fähigkeit können Sie jetzt Mimik einforceUpdate
:Code-Snippet anzeigen
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 werden sollte und in den meisten Fällen, wenn Sie ein Update erzwingen müssen, wahrscheinlich etwas falsch gemacht wird.
Vor der Reaktion 16.8.0
Nein , Sie können nicht, Staat-Less Funktionskomponenten sind nur normal ,
functions
dass die Renditenjsx
, Sie haben keinen Zugriff auf die Lebenszyklus - Methoden reagieren , da Sie nicht von der Verlängerung sindReact.Component
.Stellen Sie sich die Funktionskomponente als
render
Methodenteil der Klassenkomponenten vor.quelle
props
oderstate
Änderungen vorhanden sind. Sie können die Renderfunktion nicht erzwingen, darender
für zustandslose Komponenten keine Funktion vorhanden ist . zustandslose Komponenten sind nichtextends
React.Component
nur einfache Funktionen, die zurückgegeben werdenjsx
.In den offiziellen FAQ ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate ) wird diese Methode jetzt empfohlen, wenn Sie dies wirklich tun müssen:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0); function handleClick() { forceUpdate(); }
quelle
const [, forceUpdate] = useReducer(x => x + 1, 0);
Ich habe eine Drittanbieter-Bibliothek namens use-force-update verwendet , um das Rendern meiner reaktionsfähigen Funktionskomponenten zu erzwingen. Arbeitete wie Charme. Verwenden Sie einfach das Paket in Ihr Projekt importieren 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} />; };
quelle
useForceUpdate
verwendetuseCallback
wie in anderen Antworten erwähnt. Diese Bibliothek ist nur eine Dienstprogrammbibliothek, mit der Sie nur wenige Tastenanschläge speichern können.Haftungsausschluss: KEINE ANTWORT AUF DAS PROBLEM.
Hinterlassen Sie hier einen wichtigen Hinweis:
Wenn Sie versuchen, eine zustandslose Komponente zu erzwingen, stimmt möglicherweise etwas mit Ihrem Design nicht.
Betrachten Sie die folgenden Fälle:
quelle
Dies kann ohne explizite Verwendung von Hooks erfolgen, vorausgesetzt, Sie fügen Ihrer Komponente eine Requisite und der übergeordneten Komponente der zustandslosen Komponente einen Status hinzu:
const ParentComponent = props => { const [updateNow, setUpdateNow] = useState(true) const updateFunc = () => { setUpdateNow(!updateNow) } const MyComponent = props => { return (<div> .... </div>) } const MyButtonComponent = props => { return (<div> <input type="button" onClick={props.updateFunc} />.... </div>) } return ( <div> <MyComponent updateMe={updateNow} /> <MyButtonComponent updateFunc={updateFunc}/> </div> ) }
quelle
Die akzeptierte Antwort ist gut. Nur um es verständlicher zu machen.
Beispielkomponente:
export default function MyComponent(props) { const [updateView, setUpdateView] = useState(0); return ( <> <span style={{ display: "none" }}>{updateView}</span> </> ); }
Rufen Sie den folgenden Code auf, um ein erneutes Rendern zu erzwingen:
setUpdateView((updateView) => ++updateView);
quelle