Möchten Sie eine Funktion anfordern oder einen Fehler melden?
Es scheint ein Fehler zu sein . 😕
Wie ist das aktuelle Verhalten?
Verschachtelter Kontextanbieter und useContext
Hooks scheinen in Konflikt zu stehen, Updates werden verworfen.
Was ist das erwartete Verhalten?
Wenn Sie eine Verbindung zu einem Kontext herstellen, sollte diese aktualisiert werden, wenn sich value
ändert.
Welche Versionen von React und welcher Browser / welches Betriebssystem sind von diesem Problem betroffen?
18.8.0-alpha.1
(auch reproduziert auf 16.7.0-alpha.0
)chrome 71
Während Sie an einer Bereinigung einer localStorage- "Verbindung" arbeiten,
Ich habe versucht, 2 Artikel ( [1]
& [2]
) aus der offiziellen Reaktionsdokumentation zu mischen. Ich habe sie mit Hooks implementiert, aber der Wert scheint nicht durchzugehen.
Ich habe eine optimierte Demo für Codesandbox [3]
.
Die eigentliche Implementierung besteht nur noch aus ein paar Zeilen (Parsen und Stringisieren von JSON).
Problemumgehungen, die ich gefunden habe:
setValue
erstelle, funktioniert dies tatsächlich.[1]
, die Schaffung neuer Werte zu vermeiden.componentDidUpdate
anstelle von useEffect
.Gibt es etwas, das mit dem folgenden Code nicht funktionieren sollte? Der Effekt wird mit den Änderungen ausgelöst.
Der Wert wird jedoch nicht für die Komponenten aktualisiert, die über Hook verbraucht werden. siehe Repro-Code [3]
const createLocalStorage = key => {
const initialValue = localStorage.getItem(key)
const ValueContext = createContext(initialValue)
const SetterContext = createContext(() => {})
const useStorage = () => [ValueContext, SetterContext].map(useContext)
const Provider = ({children}) => {
const [value, setValue] = useState(initialValue)
useEffect(
() => {
console.log('effect', value)
localStorage.setItem(key, value)
},
[value],
)
return (
<ValueContext.Provider value={value}>
<SetterContext.Provider value={setValue}>
{children}
</SetterContext.Provider>
</ValueContext.Provider>
)
}
return [Provider, useStorage]
}
[1]
: https://reactjs.org/docs/hooks-faq.html#how-um zu vermeiden, dass Rückrufe weitergegeben werden
[2]
: https://reactjs.org/docs/context.html#updating -context-from-a-verschachtelte-Komponente
[3]
: https://codesandbox.io/s/0yzjr8vnrv
Ich habe eine optimierte Demo für Codesandbox [3] erstellt.
Für mich sieht es so aus, als ob sich Ihre useContext
-Anrufe in derselben Komponente befinden wie Provider
. In diesem Sinne lesen sie den Kontext über dem Provider (dem Standard).
Der Wert des Anbieters beeinflusst nur den Kontext für Komponenten innerhalb des Anbieters.
Übrigens, wenn Sie nicht versucht hätten, die Hooks-Regeln mit Code wie [A, B].map(useContext)
zu betrügen, hätten Sie das vielleicht früher bemerkt ;-)
Hey Dan! danke für die schnelle antwort (: habe es gerade für mich behoben.
Übrigens: useContext
(über useStorage
) befindet sich innerhalb von App
, was _in_ innerhalb von Provider
in der Funktion ReactDOM.render
. (Vielleicht habe ich das Beispiel zu kurz gemacht, um diese Verschachtelung zu sehen).
Lösung :
Ich habe es gerade gelöst, indem ich diese skurrile .map
-Zeile geändert habe: Ich habe den observedBits
-Parameter verpasst, der weitergegeben wurde. Ich habe es hier in den Issues / PRs gelesen, aber vergessen bei der Implementierung und endete mit dem Verhalten durcheinander.
Aaah, du hast recht, ich habe dein Beispiel falsch verstanden. Ja, observedBits
ist hier das Problem. Scheint eine Falle zu sein, aber dann empfehlen wir auch nicht, useContext
jemals dynamisch anzurufen.
Hilfreichster Kommentar
Für mich sieht es so aus, als ob sich Ihre
useContext
-Anrufe in derselben Komponente befinden wieProvider
. In diesem Sinne lesen sie den Kontext über dem Provider (dem Standard).Der Wert des Anbieters beeinflusst nur den Kontext für Komponenten innerhalb des Anbieters.
Übrigens, wenn Sie nicht versucht hätten, die Hooks-Regeln mit Code wie
[A, B].map(useContext)
zu betrügen, hätten Sie das vielleicht früher bemerkt ;-)