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()
.
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()
.
Antworten:
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>
);
}
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.
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.
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 wird setState
, wird sie nicht erneut gerendert
Update 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 ein forceUpdate
:
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 Renditen jsx
, Sie haben keinen Zugriff auf die Lebenszyklus - Methoden reagieren , da Sie nicht von der Verlängerung sind React.Component
.
Stellen Sie sich die Funktionskomponente als render
Methodenteil der Klassenkomponenten vor.
props
oder state
Änderungen vorhanden sind. Sie können die Renderfunktion nicht erzwingen, da render
fĂĽr zustandslose Komponenten keine Funktion vorhanden ist . zustandslose Komponenten sind nicht extends
React.Component
nur einfache Funktionen, die zurĂĽckgegeben werden jsx
.
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();
}
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} />;
};
useForceUpdate
verwendet useCallback
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:
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>
)
}
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);