2016-07-14 19 views
1

Es ist mein Verständnis, dass Sie nicht Zustände in der Render-Funktion ändern sollen Ursache, die verursachen würde und unendlich Rendern oder die Komponente.Reactjs: Ändern Sie den Zustand nur einige Male in Render

Das macht vollkommen Sinn, aber ich finde mich in einer bestimmten Situation. Ich erstelle eine Offline-Anwendung und verwende ein Offline-Speichersystem, um Daten abzurufen. Wann immer eine Methode aufgerufen wird, um bestimmte Daten zu erhalten, wird der Cache überprüft, wenn sie nicht abgelaufen ist, kann die Komponente auf die Daten zugreifen und daher passiert nichts, aber wenn sie abgelaufen ist, erfolgt ein Aufruf an die API, die Daten wird aktualisiert und die interessierten Komponenten neu gerendert.

Diese Methoden ändern den Zustand der Komponente beim ersten Aufruf, da sie zur API gehen und die neuen Daten erfassen und neu rendern. Dann ändern sie den Status nicht mehr, da die Daten bereits vorhanden sind im Cache.

Jetzt könnte ich diese Methoden in Komponente aufrufen wird mounten, und das ist, was ich jetzt mache, aber wenn ich gezwungen bin, sie erneut aufzurufen, muss ich die Komponenten unmounten und neu mounten. Ist das der einzig mögliche Weg?

Danke!

Antwort

1

Nun der erste Schritt ist zu verstehen, dass State Management und Rendering entkoppelt werden müssen, die Sie bereits bekommen haben.

Nun, was Sie tun können, ist Ihr externer Zustand/Cache-Element als beobachtbares Objekt (dh ich möchte etwas wie observableObject.listen('change', onChangeHandler) tun; Sie können EventsEmitter aus der events-Bibliothek verwenden). You do that listening on componentDidMount and clean up in componentWillUnmout. Das onChangeHandler ist sehr einfach: this.setState({ value: observableObject.value }), die eine Komponente neu Rendern auslösen wird, die eine reine Funktion sein sollte, die DOM-Knoten abhängig von props wird übergeben und es ist state.

Dies bedeutet, dass Ihre Logik der Überprüfung, ob der Cache ungültig ist, nicht auf eine pro Anfrage des Werts (innerhalb des Renderings), sondern eher auf das Objekt als eigenständig. Es überprüft regelmäßig, ob es seinen Zuhörern mitteilen muss, dass es sich geändert hat. Da JS keine parallele Ausführung durchführt, müssen Sie sich nicht mit Threads und Synchronisation beschäftigen. Sie wissen, dass zu dem Zeitpunkt, an dem Ihre Renderfunktion ausgeführt wird, dieser den neuesten Wert hat. Wenn nach dem Rendern der Logik, die nach dem Cache sucht, ausgeführt wird, und es sieht, dass es aktualisiert werden muss, benachrichtigt es einfach wie zuvor seine Listener und das macht Ihre Komponente erneut rendern, weil Ihre onChangeHandler die state geändert hat.

Ich hoffe, ich half.

+0

Ok, also rufe ich render() bereits aus dem Cache, wenn etwas geändert wird. Die Lösung, die Sie vorschlagen, besteht darin, dass ich nicht einfach Render aufrufen, sondern eine Methode in der Komponente aufrufen kann, die den Cache nach Bedarf aktualisiert und dann den Cache aufruft. –

+0

Ja, im Grunde erstellen Sie eine "Verbindung" zwischen diesem externen 'Cache/State' und Ihrer eigenen Komponenteninstanz' state'. Wenn man sich ändert, wird der andere benachrichtigt. Etwas wie dieses: 'this.props.myCache.listen ('ändern', this.onCacheChange)' und 'this.onCacheChange =() => this.setState ({value: this.props.myCache.getValue ()}); Weitere Informationen zu React ['setState'] (https://facebook.github.io/react/docs/component-api.html). – AlexandruB

+0

Ja, aber das passiert schon. Also, sagen wir, etwas löscht den Cache. Cache löst einen erneuten Aufruf aller Seiten aus, die interessiert sind. Das Problem ist, dass Methoden, die in ComponentWillMount aufgerufen werden, aufgerufen werden müssen und rufen Sie die API erneut auf und ändern Sie den Cache, der wiederum ein erneutes Rendern verursacht. Hat dies mir eine Lösung vorgeschlagen, nicht nur das Rendern aus dem Cache, sondern das Aufrufen einer Methode in meiner Komponente, die asiapi aufruft und dann wieder rendert. –