Leere Abhängigkeiten mit useMemo oder useCallback VS useRef

9

In dieser GitHub-Ausgabe habe ich im Wesentlichen vorgeschlagen, Folgendes zu ändern:

x = useCallback( ... , []);

Zu:

x = useRef( ... ).current;

Die beiden sind gleich, aber mit useRefReact werden die Abhängigkeiten nicht verglichen.

Auf die eine Antwort mit einer Frage kam:

Gibt es jemals eine Situation, in der ein abhängigkeitsloses useMemo oder useCallback die bessere Wahl wäre als useRef?

Ich kann mir keinen vorstellen, aber ich habe möglicherweise einige Anwendungsfälle übersehen.

Kann sich jemand eine solche Situation vorstellen?

Izhaki
quelle

Antworten:

5

Pro React Hooks API-Dokumentation:

Beachten Sie, dass useRef Sie nicht benachrichtigt, wenn sich der Inhalt ändert. Das Mutieren der .current-Eigenschaft führt nicht zu einem erneuten Rendern . Durch die Verwendung einer Rückrufreferenz wird sichergestellt, dass auch dann, wenn eine untergeordnete Komponente den gemessenen Knoten später anzeigt (z. B. als Reaktion auf einen Klick), wir im übergeordneten Knoten darüber benachrichtigt werden Komponente und kann die Messungen aktualisieren.

Hier und hier können Sie mehr darüber lesen .

irasuna
quelle
Ich denke, dies beantwortet die Frage, aber ich vermute, dass dies falsch ist. Im Beispiel "Sandbox reagieren" funktioniert das Ändern useCallback(x,[])in " useRef(x)genauso".
Izhaki
useRef(x).currentdas ist.
Izhaki
Ich hoffe, ich liege falsch, aber ich habe begründet, warum die Dokumente falsch sind: github.com/reactjs/reactjs.org/issues/2570
Izhaki
Ich bin nicht ganz sicher , in Bezug auf useCallback(cb, [])vs useRef(cb).currentmir. Obwohl, useMemo(cb, [])zu unterschiedlich ist useRef(cb).currentin einem gewissen Sinne , dass useMemo„nur den memoized Wert neu berechnet , wenn eine der Abhängigkeiten geändert hat.“ Versus, useRefdie den Wert immer neu berechnen, egal was passiert.
Irauna
useRefNie neu berechnet - es wird immer der Anfangswert zurückgegeben.
Izhaki
1

Während Sie useRef verwenden können, um useCallback oder mit einer leeren Abhängigkeit zu emulieren, können Sie es nicht für alle möglichen Szenarien von useCallback verwenden, die sich daran erinnern sollen, wenn sich eine der Abhängigkeiten ändert.

Außerdem macht es keinen großen Leistungsunterschied, wenn Sie useCallback with empty dependencyRef verwenden oder verwenden, da es keinen umfangreichen Vergleich durchführen muss.

Wenn Sie die Funktionsimplementierung ein wenig ändern, sodass Sie sie bei einer bestimmten Parameteränderung neu erstellen müssen, können Sie die Implementierung einfach mit aktualisieren useCallbackund den zusätzlichen Parameter als Abhängigkeit hinzufügen. Wenn Sie es jedoch mit useRef implementieren, müssen Sie zu zurückkehrenuseCallback

Shubham Khatri
quelle
1
Vielen Dank. Wie der Titel schon sagt, handelt es sich hierbei um einen streng leeren Abhängigkeitsfall.
Izhaki
1
@Izhaki Ich verstehe, dass Ihre Frage streng leere Abhängigkeiten sind, und deshalb habe ich erwähnt, dass es bei leeren Abhängigkeiten keinen Unterschied gibt. Aber wenn Sie versuchen, weitere Änderungen hinzuzufügen, benötigen Sie möglicherweise einiges an Refactor
Shubham Khatri,
0

Weil die Ausgabe von useRef (() => {...}). Current veränderlich ist.

Was seltsame Nebenwirkungen in Ihrem Code verursachen kann. Ich kann den Stromwert jederzeit ändern. https://codesandbox.io/s/confident-monad-vjeuw

Dies wäre der Grund dafür, dass useRef nicht verwendet werden soll

Daniel Duong
quelle
1
x = useRef(value).currentGibt aber niemals veränderbare Instanzen zurück - refwird niemals zurückgegeben; currentist. Das ist das gleiche wie bei der useCallbackVersion.
Izhaki