Ich habe ein externes (für die Komponente) beobachtbares Objekt, auf das ich nach Änderungen warten möchte. Wenn das Objekt aktualisiert wird, werden Änderungsereignisse ausgegeben, und dann möchte ich die Komponente erneut rendern, wenn eine Änderung erkannt wird.
Mit einer obersten Ebene war React.render
dies möglich, aber innerhalb einer Komponente funktioniert es nicht (was sinnvoll ist, da die render
Methode nur ein Objekt zurückgibt).
Hier ist ein Codebeispiel:
export default class MyComponent extends React.Component {
handleButtonClick() {
this.render();
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick.bind(this)}>
Click me
</button>
</div>
)
}
}
Wenn Sie intern auf die Schaltfläche klicken this.render()
, wird das Rendern nicht ausgeführt (dies kann jedoch in Aktion angezeigt werden, da sich der von erstellte Text {Math.random()}
nicht ändert). Allerdings, wenn ich einfach anrufen this.setState()
statt this.render()
, es funktioniert gut.
Also ich meine Frage erraten ist: Reagieren Komponenten müssen Staat , um rerender haben? Gibt es eine Möglichkeit, die Komponente zu zwingen, bei Bedarf zu aktualisieren, ohne den Status zu ändern?
this.forceUpdate()
die richtige Lösung ist, während der Rest aller Antworten und mehrere Kommentare gegen die Verwendung sindforceUpdate()
. Wird das dann in Ordnung sein zu sagen, dass die Frage noch keine richtige Lösung / Antwort bekommen hat?Antworten:
In Ihrer Komponente können Sie aufrufen
this.forceUpdate()
, um ein erneutes Rendern zu erzwingen.Dokumentation: https://facebook.github.io/react/docs/component-api.html
quelle
this.forceUpdate()
nicht eine sehr gute Lösung für das Problem Fragesteller ist, es ist die richtige Antwort auf die Frage im Titel gestellt. Obwohl dies generell vermieden werden sollte, gibt es Situationen, in denen forceUpdate eine gute Lösung ist.shouldComponentUpdate()
Ihre Lösung nutzlos zu machen.forceUpdate
sollte vermieden werden, da es von einer React-Denkweise abweicht. In den React-Dokumenten wird ein Beispiel fürforceUpdate
die Verwendung angegeben:Ich möchte jedoch die Idee vorschlagen, dass selbst bei tief verschachtelten Objekten dies nicht erforderlich
forceUpdate
ist. Durch die Verwendung einer unveränderlichen Datenquelle werden Änderungen nachverfolgt. Eine Änderung führt immer zu einem neuen Objekt, sodass wir nur prüfen müssen, ob sich der Verweis auf das Objekt geändert hat. Sie können die Bibliothek Immutable JS verwenden , um unveränderliche Datenobjekte in Ihre App zu implementieren.Das Ändern des Schlüssels des Elements, das neu gerendert werden soll, funktioniert. Stellen Sie die Schlüsselstütze für Ihr Element über den Status ein und dann, wenn Sie den Status aktualisieren möchten, um einen neuen Schlüssel zu erhalten.
Dann erfolgt eine Änderung und Sie setzen den Schlüssel zurück
Ich möchte darauf hinweisen, dass dies das Element ersetzt, auf dem sich der Schlüssel ändert. Ein Beispiel dafür, wo dies nützlich sein könnte, ist, wenn Sie ein Dateieingabefeld haben, das Sie nach einem Bild-Upload zurücksetzen möchten.
Die wahre Antwort auf die Frage des OP wäre, dass
forceUpdate()
ich diese Lösung in verschiedenen Situationen als hilfreich empfunden habe. Ich möchte auch darauf hinweisen, dass Sie, wenn Sie feststellen, dass Sie verwendenforceUpdate
, möglicherweise Ihren Code überprüfen und prüfen möchten, ob es eine andere Möglichkeit gibt, Dinge zu tun.ANMERKUNG 1-9-2019:
Das obige (Ändern des Schlüssels) ersetzt das Element vollständig. Wenn Sie feststellen, dass Sie den Schlüssel aktualisieren, um Änderungen vorzunehmen, liegt wahrscheinlich ein anderes Problem in Ihrem Code vor. Wenn Sie den
Math.random()
Schlüssel in verwenden, wird das Element bei jedem Rendern neu erstellt. Ich würde NICHT empfehlen, den Schlüssel so zu aktualisieren, da React den Schlüssel verwendet, um den besten Weg zum erneuten Rendern von Dingen zu bestimmen.quelle
key
. Erstens ist die Absicht unklar. Ein Leser Ihres Codes muss hart arbeiten, um zu verstehen, warum Siekey
diesen Weg verwenden. Zweitens ist dies nicht reiner alsforceUpdate
. "Reine" Reaktion bedeutet, dass die visuelle Darstellung Ihrer Komponente zu 100% von ihrem Status abhängt. Wenn Sie also einen Status ändern, wird sie aktualisiert. Wenn Sie jedoch einige tief verschachtelte Objekte haben (das Szenario, in dem dieforceUpdate
Dokumente einen Grund für die Verwendung angeben),forceUpdate
macht die Verwendung dies deutlich. DrittensMath.random()
ist… zufällig. Theoretisch könnte es die gleiche Zufallszahl erzeugen.forceUpdate
ist der React-Weg, dies zu tun.Tatsächlich
forceUpdate()
ist dies die einzig richtige Lösung, dasetState()
möglicherweise kein erneutes Rendern ausgelöst wird, wenn zusätzliche Logik in implementiert istshouldComponentUpdate()
oder wenn sie einfach zurückgegeben wirdfalse
.Update erzwingen()
setState ()
forceUpdate()
kann innerhalb Ihrer Komponente von aufgerufen werdenthis.forceUpdate()
Hooks: Wie kann ich die Komponente zwingen, mit Hooks in React neu zu rendern?
Übrigens: Mutieren Sie den Status oder verbreiten sich Ihre verschachtelten Eigenschaften nicht?
quelle
this.state
außerhalb des Konstruktors sollte ebenfalls einen Fehler auslösen . Könnte dies 2016 nicht getan haben; aber ich bin mir ziemlich sicher, dass es das jetzt tut.Ich habe es vermieden,
forceUpdate
indem ich folgendes tatWenn Sie also eine solche Codeverbesserung durchführen, ist Ihre Komponente EINZIGARTIG und wird auf natürliche Weise gerendert
quelle
this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
Wenn zwei React-Komponenten kommunizieren sollen, die nicht an eine Beziehung gebunden sind (Eltern-Kind), ist es ratsam, Flux oder ähnliche Architekturen zu verwenden.
Sie möchten auf Änderungen des
beobachtbaren Komponentenspeicherswarten, in dem sich das Modell und seine Schnittstelle befinden, und die Daten speichern, die dazu führen, dass sich das Rendering wiestate
in ändertMyComponent
. Wenn der Store die neuen Daten pusht, ändern Sie den Status Ihrer Komponente, wodurch das Rendern automatisch ausgelöst wird.Normalerweise sollten Sie versuchen, die Verwendung zu vermeiden
forceUpdate()
. Aus der Dokumentation:quelle
react-redux
, um den Speicherstatus bei Bedarf automatisch auf Komponenten-Requisiten abzubilden, basierend auf einer von Ihnen bereitgestellten Zuordnungsfunktion.forceUpdate
Verwenden Sie Haken oder HOC treffen Sie Ihre Wahl
Mithilfe von Hooks oder dem HOC-Muster (Component höherer Ordnung) können Sie automatische Aktualisierungen durchführen, wenn sich Ihre Geschäfte ändern. Dies ist ein sehr leichter Ansatz ohne Rahmen.
useStore Hooks Methode zum Behandeln von Store-Updates
withStores HOC behandelt Store-Updates
SimpleStore-Klasse
Wie benutzt man
Bei Haken:
Im Fall von HOC:
SICHERSTELLEN So exportieren Sie Ihre Geschäfte als Singleton, um die Vorteile des globalen Wandels wie folgt zu nutzen:
Dieser Ansatz ist ziemlich einfach und funktioniert für mich. Ich arbeite auch in großen Teams und benutze Redux und MobX und finde diese auch gut, aber nur viel Boilerplate. Ich persönlich mag meinen eigenen Ansatz nur, weil ich immer viel Code für etwas gehasst habe, das einfach sein kann, wenn es sein muss.
quelle
this._data = {...this._data, ...newData}
.Die anderen Antworten haben versucht zu veranschaulichen, wie Sie könnten, aber der Punkt ist, dass Sie nicht sollten . Sogar die hackige Lösung, den Schlüssel zu ändern, geht am eigentlichen Punkt vorbei. Die Kraft von React besteht darin, die Kontrolle über die manuelle Verwaltung aufzugeben, wann etwas gerendert werden soll, und stattdessen nur darüber nachzudenken, wie etwas auf Eingaben abgebildet werden soll. Dann Strom von Eingaben liefern.
Wenn Sie das erneute Rendern manuell erzwingen müssen, machen Sie mit ziemlicher Sicherheit etwas nicht richtig.
quelle
Sie können es auf verschiedene Arten tun:
1. Verwenden Sie die
forceUpdate()
Methode:Bei Verwendung der
forceUpdate()
Methode können einige Störungen auftreten . Ein Beispiel ist, dass dieshouldComponentUpdate()
Methode ignoriert wird und die Ansicht neu gerendert wird, unabhängig davon, obshouldComponentUpdate()
false zurückgegeben wird. Aus diesem Grund sollte die Verwendung von forceUpdate () nach Möglichkeit vermieden werden.2. Übergeben Sie this.state an die
setState()
MethodeDie folgende Codezeile überwindet das Problem mit dem vorherigen Beispiel:
In Wirklichkeit überschreibt dies lediglich den aktuellen Status mit dem aktuellen Status, der ein erneutes Rendern auslöst. Dies ist immer noch nicht unbedingt der beste Weg, um Dinge zu tun, aber es überwindet einige der Probleme, die bei der Verwendung der forceUpdate () -Methode auftreten können.
quelle
this.setState(prevState => prevState);
Es gibt verschiedene Möglichkeiten, Ihre Komponente neu zu rendern:
Die einfachste Lösung ist die Verwendung der forceUpdate () -Methode:
Eine weitere Lösung besteht darin, einen nicht verwendeten Schlüssel im Status (nonUsedKey) zu erstellen und die setState-Funktion mit der Aktualisierung dieses nonUsedKey aufzurufen:
Oder schreiben Sie den gesamten aktuellen Status neu:
Das Ändern von Requisiten bietet auch das Rendern von Komponenten.
quelle
Der Vollständigkeit halber können Sie dies auch in Funktionskomponenten erreichen:
Oder als wiederverwendbarer Haken:
Siehe: https://stackoverflow.com/a/53215514/2692307
Bitte beachten Sie, dass die Verwendung eines Force-Update-Mechanismus immer noch eine schlechte Praxis ist, da dies gegen die Reaktionsmentalität verstößt. Daher sollte dies nach Möglichkeit vermieden werden.
quelle
Wir können this.forceUpdate () wie folgt verwenden.
Der Elementteil 'Math.random' im DOM wird nur aktualisiert, selbst wenn Sie den setState zum erneuten Rendern der Komponente verwenden.
Alle Antworten hier sind korrekt und ergänzen die Frage zum Verständnis. Wir wissen, dass das erneute Rendern einer Komponente ohne Verwendung von setState ({}) mithilfe von forceUpdate () erfolgt.
Der obige Code wird mit setState wie folgt ausgeführt.
quelle
Nur eine weitere Antwort, um die akzeptierte Antwort zu sichern :-)
React rät von der Verwendung ab,
forceUpdate()
da sie im Allgemeinen einen sehr "dies ist der einzige Weg, dies zu tun" -Ansatz für die funktionale Programmierung haben. Dies ist in vielen Fällen in Ordnung, aber viele React-Entwickler haben einen OO-Hintergrund, und mit diesem Ansatz ist es vollkommen in Ordnung, ein beobachtbares Objekt anzuhören.Und wenn Sie dies tun, wissen Sie wahrscheinlich, dass Sie erneut rendern MÜSSEN, wenn das beobachtbare "Feuer" ausgelöst wird, und als solches sollten Sie es verwenden,
forceUpdate()
und es ist tatsächlich ein Plus, dasshouldComponentUpdate()
hier NICHT involviert ist.Tools wie MobX, die einen OO-Ansatz verfolgen, tun dies tatsächlich unter der Oberfläche (tatsächlich ruft MobX
render()
direkt auf).quelle
Ich habe es am besten gefunden, forceUpdate () zu vermeiden. Eine Möglichkeit, das erneute Rendern zu erzwingen, besteht darin, die Abhängigkeit von render () von einer temporären externen Variablen hinzuzufügen und den Wert dieser Variablen nach Bedarf zu ändern.
Hier ist ein Codebeispiel:
Rufen Sie this.forceChange () auf, wenn Sie ein erneutes Rendern erzwingen müssen.
quelle
ES6 - Ich füge ein Beispiel hinzu, das für mich hilfreich war:
In einer "kurzen if-Anweisung" können Sie eine leere Funktion wie folgt übergeben:
Dies scheint der kürzeste Ansatz zu sein.
quelle
forceUpdate();
Methode wird funktionieren, aber es ist ratsam zu verwendensetState();
quelle
Um das zu erreichen, was Sie beschreiben, versuchen Sie bitte this.forceUpdate ().
quelle
Ein anderer Weg , ruft
setState
, und bewahren Zustand:this.setState(prevState=>({...prevState}));
quelle
forceUpdate (), aber jedes Mal, wenn ich jemanden darüber sprechen hörte, sollten Sie dies niemals verwenden.
quelle
Sie können forceUpdate () verwenden, um weitere Details zu überprüfen ( forceUpdate () ).
quelle