Пустые зависимости с помощью useMemo или useCallback VS useRef

9

В этом выпуске GitHub я, по сути, предложил изменить:

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

Для того, чтобы:

x = useRef( ... ).current;

Они одинаковы, но с useRefReact не сравнивает зависимости.

На что пришел ответ с вопросом:

Была ли когда-нибудь ситуация, когда использование useMemo или useCallback без зависимости было бы лучшим выбором, чем useRef?

Я не могу думать об одном, но я мог пропустить некоторые варианты использования.

Так может кто-нибудь придумать такую ​​ситуацию?

Izhaki
источник

Ответы:

5

Документация по API React Hooks:

Имейте в виду, что useRef не уведомляет вас, когда его содержимое изменяется. Отключение свойства .current не вызывает повторного рендеринга ... Использование обратного вызова ref гарантирует, что даже если дочерний компонент отобразит измеренный узел позже (например, в ответ на щелчок), мы все равно получим уведомление об этом в родительском элементе. компонент и может обновить измерения.

Вы можете прочитать больше об этом здесь и здесь .

irasuna
источник
Я думаю, что это отвечает на вопрос, но я подозреваю, что это неправильно. В примере с песочницей React, меняется useCallback(x,[])на useRef(x)тот же.
Ижаки
useRef(x).currentэто.
Ижаки
Надеюсь, я ошибаюсь, но я объяснил, почему документы не так: github.com/reactjs/reactjs.org/issues/2570
Изаки,
Я не совсем уверен относительно useCallback(cb, [])против useRef(cb).currentсебя. Хотя useMemo(cb, [])отличается от useRef(cb).currentтого useMemo, что «пересчитывает запомненное значение только тогда, когда одна из зависимостей изменилась». По сравнению с тем, useRefкоторый всегда пересчитывает значение, несмотря ни на что.
Ирасуна
useRefникогда не пересчитывает - всегда возвращает начальное значение.
Ижаки
1

В то время как вы можете использовать useRef для эмуляции useCallback или с пустой зависимостью, вы не можете использовать его для всех возможных сценариев useCallback, который должен помнить, когда изменяется любая из зависимостей.

Кроме того, это не будет иметь большого значения для производительности, если вы используете useCallback with empty dependencyили используете Ref, так как он не должен выполнять никаких тяжелых сравнений.

Также, если вы немного измените реализацию функции, чтобы вам пришлось воссоздать ее при конкретном изменении параметра, вы можете просто обновить реализацию useCallbackи добавить дополнительный параметр в качестве зависимости. Однако, если вы реализуете это с помощью useRef, вы должны вернуться кuseCallback

Шубхам Хатри
источник
1
Спасибо. Как видно из названия, это строго пустой случай зависимостей.
Ижаки
1
@Izhaki Я понимаю, что ваш вопрос - это строго пустые зависимости, и поэтому я упомянул, что нет никакой разницы в случае пустой зависимости. Но когда вы пытаетесь добавить больше изменений, вам может понадобиться немного рефакторинга
Шубхам Хатри
0

Потому что выходные данные useRef (() => {...}). Current являются изменяемыми.

Что может вызвать странные побочные эффекты в вашем коде. Я могу изменить значение тока в любое время. https://codesandbox.io/s/confident-monad-vjeuw

Это был бы сценарий отказа от использования useRef.

Дэниел Дуонг
источник
1
Но x = useRef(value).currentникогда не возвращает изменяемые экземпляры - refникогда не возвращается; currentявляется. Это так же, как с useCallbackверсией.
Изаки