Können Sie eine React-Komponente zum erneuten Rendern zwingen, ohne setState aufzurufen?

687

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.renderdies möglich, aber innerhalb einer Komponente funktioniert es nicht (was sinnvoll ist, da die renderMethode 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?

Philip Walton
quelle
7
Die akzeptierte Antwort besagt, dass dies this.forceUpdate()die richtige Lösung ist, während der Rest aller Antworten und mehrere Kommentare gegen die Verwendung sind forceUpdate(). Wird das dann in Ordnung sein zu sagen, dass die Frage noch keine richtige Lösung / Antwort bekommen hat?
adi
6
Die ausgenommene Antwort beantwortete meine damalige Frage. Es ist technisch die Antwort, nach der ich gesucht habe, und ich denke immer noch die richtige Antwort. Die anderen Antworten sind meiner Meinung nach gute ergänzende Informationen für Leute mit der gleichen Frage, die sie kennen sollten.
Philip Walton
Interessant ist, dass Sie im Status nichts anderes benötigen, als es mit einem einfachen Objekt zu initialisieren. Wenn Sie dann this.setState ({}) aufrufen, wird nur ein neues Rendering ausgelöst. Die Reaktion ist großartig, aber manchmal auch komisch. Daher können Sie beim Auslösen einer Änderung direkt eine Speicherung durch die gespeicherten Daten durchführen, ohne zusätzliche Installationsarbeiten ausführen oder sich um Daten pro Komponenteninstanz kümmern zu müssen.
Jason Sebring
Im Großen und Ganzen würde ich ja sagen. Wenn Sie Force Update verwenden, dient dies zum Aktualisieren von Komponenten, bei denen sie möglicherweise von Änderungen außerhalb der Statusverwaltung Ihrer App abhängig sind. Ich kann mir kein gutes Beispiel dafür vorstellen. Nützlich zu wissen.
Daniel

Antworten:

764

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

Crob
quelle
168
Ein anderer Weg ist this.setState (this.state);
Kar
25
Von der Verwendung von forceupdate wird abgeraten. Weitere Informationen finden Sie in der letzten Antwort.
Varand Pezeshkian
42
Während 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.
ArneHugo
8
@kar Tatsächlich kann zusätzliche Logik implementiert werden, um shouldComponentUpdate()Ihre Lösung nutzlos zu machen.
Qwerty
4
Maximale Call-Stack-Größe überschritten
IntoTheDeep
326

forceUpdatesollte vermieden werden, da es von einer React-Denkweise abweicht. In den React-Dokumenten wird ein Beispiel für forceUpdatedie Verwendung angegeben:

Wenn sich der Status oder die Requisiten Ihrer Komponente ändern, wird Ihre Komponente standardmäßig neu gerendert. Wenn sich diese jedoch implizit ändern (z. B. Daten tief in einem Objekt ändern, ohne das Objekt selbst zu ändern) oder wenn Ihre render () -Methode von anderen Daten abhängt, können Sie React durch Aufrufen mitteilen, dass render () erneut ausgeführt werden muss Update erzwingen().

Ich möchte jedoch die Idee vorschlagen, dass selbst bei tief verschachtelten Objekten dies nicht erforderlich forceUpdateist. 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.

Normalerweise sollten Sie versuchen, alle Verwendungen von forceUpdate () zu vermeiden und nur aus this.props und this.state in render () zu lesen. Dies macht Ihre Komponente "rein" und Ihre Anwendung viel einfacher und effizienter. Update erzwingen()

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.

<Element key={this.state.key} /> 

Dann erfolgt eine Änderung und Sie setzen den Schlüssel zurück

this.setState({ key: Math.random() });

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 verwenden forceUpdate, 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.

Pizzarob
quelle
16
Es würde mich interessieren, warum dies eine negative Bewertung erhielt. Ich habe mir den Kopf geschlagen, um Bildschirmleser dazu zu bringen, auf Arienalarme zu reagieren, und dies ist die einzige Technik, die ich gefunden habe und die zuverlässig funktioniert. Wenn Ihre Benutzeroberfläche etwas enthält, das bei jedem Klicken dieselbe Warnung generiert, wird das DOM standardmäßig durch "Reagieren" nicht erneut gerendert, sodass der Bildschirmleser die Änderung nicht ankündigt. Durch das Festlegen eines eindeutigen Schlüssels funktioniert es. Vielleicht lag die Ablehnung daran, dass es immer noch darum geht, den Status festzulegen. Das Erzwingen eines erneuten Renderns in DOM durch Einstellen des Schlüssels ist jedoch golden!
Martin Bayly
2
Diese Antwort hat mir sehr gut gefallen, weil - 1: von der Verwendung von forceupdate () abgeraten wird und 2: diese Methode für Komponenten von Drittanbietern, die Sie über npm installiert haben, sehr hilfreich ist, dh nicht für Ihre eigenen Komponenten. Beispiel: React-resizable-and-movable ist eine Komponente eines Drittanbieters, die ich verwende, die jedoch nicht auf den Status meiner Komponente reagiert. Das ist eine großartige Lösung.
Varand Pezeshkian
80
Dies ist ein Hack und ein Missbrauch von key. Erstens ist die Absicht unklar. Ein Leser Ihres Codes muss hart arbeiten, um zu verstehen, warum Sie keydiesen Weg verwenden. Zweitens ist dies nicht reiner als forceUpdate. "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 die forceUpdateDokumente einen Grund für die Verwendung angeben), forceUpdatemacht die Verwendung dies deutlich. Drittens Math.random()ist… zufällig. Theoretisch könnte es die gleiche Zufallszahl erzeugen.
Atomkirk
8
@xtraSimplicity Ich kann nicht zustimmen, dass dies der React-Methode entspricht. forceUpdateist der React-Weg, dies zu tun.
Rob Grant
3
@ Robert Grant, rückblickend stimme ich zu. Die zusätzliche Komplexität ist es nicht wirklich wert.
XtraSimplicity
80

Tatsächlich forceUpdate()ist dies die einzig richtige Lösung, da setState()möglicherweise kein erneutes Rendern ausgelöst wird, wenn zusätzliche Logik in implementiert ist shouldComponentUpdate()oder wenn sie einfach zurückgegeben wird false.

Update erzwingen()

Beim Aufrufen forceUpdate()wird render()die Komponente aufgerufen und übersprungen shouldComponentUpdate(). Mehr...

setState ()

setState()löst immer ein erneutes Rendern aus, es sei denn, die bedingte Renderlogik ist in implementiert shouldComponentUpdate(). Mehr...


forceUpdate() kann innerhalb Ihrer Komponente von aufgerufen werden this.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?

Qwerty
quelle
1
Eine interessante Sache zu beachten ist, dass Zustandsbewertungen außerhalb von setState wie this.state.foo = 'bar' die Render-Lebenszyklusmethode nicht auslösen
lfender6445
4
@ lfender6445 Das Zuweisen eines Status direkt mit this.stateauß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.
Tyler
Ich habe einige Links hinzugefügt, um direkte Zustandszuweisungen zu umgehen.
Qwerty
36

Ich habe es vermieden, forceUpdateindem ich folgendes tat

FALSCHER WEG : Verwenden Sie den Index nicht als Schlüssel

this.state.rows.map((item, index) =>
   <MyComponent cell={item} key={index} />
)

RICHTIGER WEG : Verwenden Sie die Daten-ID als Schlüssel. Dies kann eine Anleitung sein

this.state.rows.map((item) =>
   <MyComponent item={item} key={item.id} />
)

Wenn Sie also eine solche Codeverbesserung durchführen, ist Ihre Komponente EINZIGARTIG und wird auf natürliche Weise gerendert

Vijay
quelle
this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
Tal
Vielen Dank, dass Sie mich in die richtige Richtung gebracht haben. Die Verwendung des Index als Schlüssel war in der Tat mein Problem.
RoiEX
Um meine Ablehnung zu rechtfertigen, obwohl diese Vorgehensweise eine gute Praxis ist, bezieht sich diese Antwort nicht auf die Frage.
Micnic
34

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 Komponentenspeichers warten, in dem sich das Modell und seine Schnittstelle befinden, und die Daten speichern, die dazu führen, dass sich das Rendering wie statein ändert MyComponent. 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:

Normalerweise sollten Sie versuchen, alle Verwendungen von forceUpdate () zu vermeiden und nur aus this.props und this.state in render () zu lesen. Dies macht Ihre Anwendung viel einfacher und effizienter

gcedo
quelle
2
Wie ist der Speicherstatus eines Komponentenzustands? Wenn ich fünf Komponenten auf einer Seite habe und alle einen einzelnen Speicher abhören, habe ich die Daten fünfmal im Speicher oder handelt es sich um Verweise? Und summieren sich nicht alle diese Zuhörer schnell? Warum ist es besser, "herunterzulaufen", als nur Daten an Ihr Ziel zu übergeben?
AJFarkas
5
Tatsächlich wird empfohlen, die Speicherdaten an Komponenten-Requisiten zu übergeben und den Komponentenstatus nur für Dinge wie den Bildlaufstatus und andere kleinere UI-spezifische Dinge zu verwenden. Wenn Sie Redux verwenden (ich empfehle es), können Sie die Verbindungsfunktion von verwenden react-redux, um den Speicherstatus bei Bedarf automatisch auf Komponenten-Requisiten abzubilden, basierend auf einer von Ihnen bereitgestellten Zuordnungsfunktion.
Stijn de Witt
1
@AJFarkas der Status wird den Daten eines Geschäfts zugewiesen, was ohnehin nur ein Zeiger darauf ist, sodass der Speicher kein Problem darstellt, es sei denn, Sie klonen.
Jason Sebring
4
"forceUpdate () sollte immer vermieden werden" ist falsch. In der Dokumentation heißt es eindeutig: "Normalerweise sollten Sie versuchen, alle Verwendungen von forceUpdate () zu vermeiden." Es gibt gültige Anwendungsfälle vonforceUpdate
AJP
2
@AJP du hast absolut recht, das war persönliche Voreingenommenheit :) Ich habe die Antwort bearbeitet.
Gcedo
18

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

interface ISimpleStore {
  on: (ev: string, fn: () => void) => void;
  off: (ev: string, fn: () => void) => void;
}

export default function useStore<T extends ISimpleStore>(store: T) {
  const [storeState, setStoreState] = useState({store});
  useEffect(() => {
    const onChange = () => {
      setStoreState({store});
    }
    store.on('change', onChange);
    return () => {
      store.off('change', onChange);
    }
  }, []);
  return storeState.store;
}

withStores HOC behandelt Store-Updates

export default function (...stores: SimpleStore[]) {
  return function (WrappedComponent: React.ComponentType<any>) {
    return class WithStore extends PureComponent<{}, {lastUpdated: number}> {
      constructor(props: React.ComponentProps<any>) {
        super(props);
        this.state = {
          lastUpdated: Date.now(),
        };
        this.stores = stores;
      }

      private stores?: SimpleStore[];

      private onChange = () => {
        this.setState({lastUpdated: Date.now()});
      };

      componentDidMount = () => {
        this.stores &&
          this.stores.forEach((store) => {
            // each store has a common change event to subscribe to
            store.on('change', this.onChange);
          });
      };

      componentWillUnmount = () => {
        this.stores &&
          this.stores.forEach((store) => {
            store.off('change', this.onChange);
          });
      };

      render() {
        return (
          <WrappedComponent
            lastUpdated={this.state.lastUpdated}
            {...this.props}
          />
        );
      }
    };
  };
}

SimpleStore-Klasse

import AsyncStorage from '@react-native-community/async-storage';
import ee, {Emitter} from 'event-emitter';

interface SimpleStoreArgs {
  key?: string;
  defaultState?: {[key: string]: any};
}

export default class SimpleStore {
  constructor({key, defaultState}: SimpleStoreArgs) {
    if (key) {
      this.key = key;
      // hydrate here if you want w/ localState or AsyncStorage
    }
    if (defaultState) {
      this._state = {...defaultState, loaded: false};
    } else {
      this._state = {loaded: true};
    }
  }
  protected key: string = '';
  protected _state: {[key: string]: any} = {};
  protected eventEmitter: Emitter = ee({});
  public setState(newState: {[key: string]: any}) {
    this._state = {...this._state, ...newState};
    this.eventEmitter.emit('change');
    if (this.key) {
      // store on client w/ localState or AsyncStorage
    }
  }
  public get state() {
    return this._state;
  }
  public on(ev: string, fn:() => void) {
    this.eventEmitter.on(ev, fn);
  }
  public off(ev: string, fn:() => void) {
    this.eventEmitter.off(ev, fn);
  }
  public get loaded(): boolean {
    return !!this._state.loaded;
  }
}

Wie benutzt man

Bei Haken:

// use inside function like so
const someState = useStore(myStore);
someState.myProp = 'something';

Im Fall von HOC:

// inside your code get/set your store and stuff just updates
const val = myStore.myProp;
myOtherStore.myProp = 'something';
// return your wrapped component like so
export default withStores(myStore)(MyComponent);

SICHERSTELLEN So exportieren Sie Ihre Geschäfte als Singleton, um die Vorteile des globalen Wandels wie folgt zu nutzen:

class MyStore extends SimpleStore {
  public get someProp() {
    return this._state.someProp || '';
  }
  public set someProp(value: string) {
    this.setState({...this._state, someProp: value});
  }
}
// this is a singleton
const myStore = new MyStore();
export {myStore};

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.

Jason Sebring
quelle
2
Ich denke, es gibt einen Tippfehler in Ihrem Store-Klassenbeispiel in der Update-Methode, der die erste Zeile der Methode wie folgt schreiben muss : this._data = {...this._data, ...newData}.
Norbert
2
React entmutigt die Vererbung zugunsten der Komposition. reactjs.org/docs/composition-vs-inheritance.html
Fred
1
Ich frage mich nur über Klarheit / Lesbarkeit, wie könnte this.setState (this.state) besser sein als this.forceUpdate ()?
Zoman
17

Meine Frage lautet also: Müssen React-Komponenten einen Status haben, um erneut gerendert zu werden? Gibt es eine Möglichkeit, die Komponente zu zwingen, bei Bedarf zu aktualisieren, ohne den Status zu ändern?

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.

Kyle Baker
quelle
@ art-solopov, auf welches Problem beziehen Sie sich? Welche Dokumente präsentieren sie? Angenommen, Sie beziehen sich auf verschachtelte Objekte im Status, besteht die Antwort darin, eine andere Struktur zum Speichern Ihres Status zu verwenden. Dies ist eindeutig eine nicht optimale Methode zur Behandlung des Status in React. Sie sollten den Status auch nicht separat verwalten. Sie verlieren einen der größten Vorteile von React, wenn Sie nicht mit dem State-Management-System arbeiten. Das manuelle Verwalten von Updates ist ein Anti-Pattern.
Kyle Baker
Können Sie diese Frage bitte überprüfen stackoverflow.com/questions/61277292/… ?
HuLu ViCa
4

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 die shouldComponentUpdate()Methode ignoriert wird und die Ansicht neu gerendert wird, unabhängig davon, ob shouldComponentUpdate()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()Methode

Die folgende Codezeile überwindet das Problem mit dem vorherigen Beispiel:

this.setState(this.state);

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.

kojow7
quelle
2
Da setState gestapelt ist, ist es wahrscheinlich sicherer:this.setState(prevState => prevState);
Mark Galloway
1
Ich bin mir nicht sicher, warum das eine Panne ist. Der Name der Methode ('forceUpdate') könnte nicht klarer sein: Erzwingen Sie die Aktualisierung immer.
Zoman
4

Es gibt verschiedene Möglichkeiten, Ihre Komponente neu zu rendern:

Die einfachste Lösung ist die Verwendung der forceUpdate () -Methode:

this.forceUpdate()

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:

this.setState({ nonUsedKey: Date.now() } );

Oder schreiben Sie den gesamten aktuellen Status neu:

this.setState(this.state);

Das Ändern von Requisiten bietet auch das Rendern von Komponenten.

Jackkobec
quelle
3

Der Vollständigkeit halber können Sie dies auch in Funktionskomponenten erreichen:

const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
// ...
forceUpdate();

Oder als wiederverwendbarer Haken:

const useForceUpdate = () => {
  const [, updateState] = useState();
  return useCallback(() => updateState({}), []);
}
// const forceUpdate = useForceUpdate();

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.

Lukas Bach
quelle
2

Wir können this.forceUpdate () wie folgt verwenden.

       class MyComponent extends React.Component {



      handleButtonClick = ()=>{
          this.forceUpdate();
     }


 render() {

   return (
     <div>
      {Math.random()}
        <button  onClick={this.handleButtonClick}>
        Click me
        </button>
     </div>
    )
  }
}

 ReactDOM.render(<MyComponent /> , mountNode);

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.

 class MyComponent extends React.Component {



             handleButtonClick = ()=>{
                this.setState({ });
              }


        render() {
         return (
  <div>
    {Math.random()}
    <button  onClick={this.handleButtonClick}>
      Click me
    </button>
  </div>
)
  }
 }

ReactDOM.render(<MyComponent /> , mountNode);
Dhana
quelle
1

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, das shouldComponentUpdate()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).

Plaul
quelle
0

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:

class Example extends Component{
   constructor(props){
      this.state = {temp:0};

      this.forceChange = this.forceChange.bind(this);
   }

   forceChange(){
      this.setState(prevState => ({
          temp: prevState.temp++
      })); 
   }

   render(){
      return(
         <div>{this.state.temp &&
             <div>
                  ... add code here ...
             </div>}
         </div>
      )
   }
}

Rufen Sie this.forceChange () auf, wenn Sie ein erneutes Rendern erzwingen müssen.

Raksheetbhat
quelle
0

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:

isReady ? ()=>{} : onClick

Dies scheint der kürzeste Ansatz zu sein.

()=>{}
MrDoda
quelle
0

forceUpdate(); Methode wird funktionieren, aber es ist ratsam zu verwenden setState();

Chiamaka Ikeanyi
quelle
0

Um das zu erreichen, was Sie beschreiben, versuchen Sie bitte this.forceUpdate ().

API-Andy
quelle
Was macht diese Aktion?
Dominique
0

Ein anderer Weg , ruft setState, und bewahren Zustand:

this.setState(prevState=>({...prevState}));

dvvtms
quelle
0

forceUpdate (), aber jedes Mal, wenn ich jemanden darüber sprechen hörte, sollten Sie dies niemals verwenden.

Ian
quelle
-1

Sie können forceUpdate () verwenden, um weitere Details zu überprüfen ( forceUpdate () ).

Harshit Singhai
quelle
1
Warum aus Neugier diese Antwort lassen, wenn die Leute dies bereits seit 4 Jahren als mögliche Lösung in diesem Thread anbieten?
Byron Coetsee