Opróżnij zależności przy użyciu useMemo lub useCallback VS useRef

9

W tym numerze GitHub zasadniczo zaproponowałem zmianę:

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

Do:

x = useRef( ... ).current;

Oba są takie same, ale w useRefReact nie porównuje zależności.

Na które nadeszła odpowiedź z pytaniem:

Czy kiedykolwiek zdarza się sytuacja, w której useMemo lub useCallback bez zależności byłoby lepszym wyborem niż useRef?

Nie mogę wymyślić jednego, ale mogłem przeoczyć niektóre przypadki użycia.

Czy ktoś może pomyśleć o takiej sytuacji?

Izhaki
źródło

Odpowiedzi:

5

Dokumentacja API Per React Hooks:

Pamiętaj, że useRef nie powiadamia Cię o zmianie treści. Mutowanie właściwości .current nie powoduje ponownego renderowania ... Użycie odwołania zwrotnego zapewnia, że ​​nawet jeśli komponent potomny wyświetli zmierzony węzeł później (np. W odpowiedzi na kliknięcie), nadal otrzymamy powiadomienie o tym w rodzicie komponent i może aktualizować pomiary.

Możesz przeczytać więcej o tym tutaj i tutaj .

irasuna
źródło
Wydaje mi się, że to odpowiada na pytanie, ale podejrzewam, że jest to nieprawidłowe. W przykładzie piaskownicy React, zmiana useCallback(x,[])na useRef(x)działa tak samo.
Izhaki,
useRef(x).currentto jest.
Izhaki
Mam nadzieję, że się mylę, ale uzasadniłem, dlaczego dokumenty są w błędzie: github.com/reactjs/reactjs.org/issues/2570
Izhaki
Nie jestem do końca pewien dotyczące useCallback(cb, [])vs useRef(cb).currentsiebie. Chociaż useMemo(cb, [])różni się useRef(cb).currentw pewnym sensie, że useMemo„ponownie obliczy zapamiętaną wartość tylko wtedy, gdy zmieni się jedna z zależności”. W przeciwieństwie do tych, useRefktóre zawsze przeliczają wartość bez względu na wszystko.
irasuna
useRefnigdy nie przelicza - zawsze zwraca wartość początkową.
Izhaki,
1

Chociaż możesz użyć useRef do emulacji useCallback lub z pustą zależnością, nie możesz go użyć do wszystkich możliwych scenariuszy useCallback, które mają zostać zapamiętane, gdy zmieni się dowolna z zależności.

Również nie zrobi to dużej różnicy w wydajności, jeśli użyjesz useCallback with empty dependencylub użyjeszRef, ponieważ nie musi wykonywać żadnego ciężkiego porównania.

Również jeśli nieco zmienisz implementację funkcji, abyś musiał odtworzyć ją przy określonej zmianie parametru, możesz po prostu zaktualizować implementację useCallbacki dodać dodatkowy parametr jako zależność. Jeśli jednak zaimplementujesz go za pomocą useRef, musisz wrócić douseCallback

Shubham Khatri
źródło
1
Dzięki. Jak sugeruje tytuł, jest to całkowicie pusty przypadek zależności.
Izhaki,
1
@Izhaki Rozumiem, że twoje pytanie jest ściśle puste zależności i dlatego wspomniałem, że nie ma żadnej różnicy w przypadku pustej zależności. Ale kiedy próbujesz dodać więcej zmian, może być potrzebny trochę refaktora
Shubham Khatri
0

Ponieważ dane wyjściowe useRef (() => {...}). Prąd jest zmienny.

Co może powodować dziwne skutki uboczne w kodzie. W każdej chwili mogę zmienić wartość prądu. https://codesandbox.io/s/confident-monad-vjeuw

Byłby to przypadek użycia, dla którego nie chce się używać useRef

Daniel Duong
źródło
1
Ale x = useRef(value).currentnigdy nie zwraca zmiennych instancji - refnigdy nie jest zwracane; currentjest. Tak samo jest z useCallbackwersją.
Izhaki,