Разница между useMemo и useCallback подробно

—

от автора

useCallback используется для мемоизации коллбеков в компонентах, а useMemo используется для мемоизации значений. По своей сути, эти два хука ничем не отличаются и предназначение у них одно и тоже — хранение данных. Строение идентичное, как и в useEffect и useLayoutEffect, первым аргументом идёт коллбек и вторым — массив зависимостей.

Вот несколько вопросов:

  • Зачем использовать два метода для одной цели?

  • Почему бы просто не вернуть данные или JXS из useCallback и использовать их?

  • Какая разница между этими двумя методами?

Разница в месте вызова

useMemo вызывается исходниками React’а, а useCallback — мы. Примеры обоих функций:

function memoUsed() {   const _  = useMemo(() => {     return ‘insert JSX here’   })    return _ }  function callbackUsed() {   const _  = useCallback(() => {     return ‘insert JSX here’   })    return _() }

Вуаля, функция useMemo имитирована очень даже прилично, с помощью вызова коллбека (6 и 14 строки). Одна вещь сделано двумя не много разными способами. Дело в том, что в “память” компоненты при пользовании useMemo попадает значение только из return, игнорируя остальное тело функции. В случае с useCallback — коллбек передаётся как строка, без вызова. Но эта разница не влияет на количество маунтов или рендеров компоненты, записи в плане производительности эквивалентны.

В useMemo не рекомендуется использовать другие хуки

Примерчик:

function memoUsed() {   const [state, setState] = useState(null)    const _  = useMemo(() => {     // причинит бесконечный ре-рендер     setState(‘value’)     return ‘insert JSX here’   })    return _ }  function callbackUsed() {   const [state, setState] = useState(null)    const _  = useCallback(() => {     // обычное дело     setState(‘value’)     return ‘insert JSX here’   })    return _() }

При вызове постороннего хука в useMemo и сопутствующем изменении состояния компонента приведёт к зацикливанию. Так как useMemo отрабатывает при стадии рендеринга, модификация состояния компонента запустит процесс заново. С useCallback таких проблем нет, функция вызывается по пользовательскому событию.

В useMemo аргумент-функция не принимает параметры

Ближе к делу:

function memoUsed() {   const _  = useMemo((arg1) => {     // React игнорирует аргументы     return ‘insert JSX here’   }, [])    return _ }  function callbackUsed() {   const _  = useCallback((what, where) => {     // могут быть использованы в функции     return ‘insert ${what} ${where}’   })    return _(‘JSX’, ‘here’) }

По документации для useCallback массив зависимостей обязателен

А для useMemo может являться и undefined, что не совсем точно. При отсутствии массива зависимостей в обоих хуках происходит ре-рендер в ста процентах случаев. Это описание является ошибкой, про что заявлено в комментарии в исходном коде.

// allow undefined, but don't make it optional as that is very likely a mistake

В целом, хук useMemo можно заменить судя по всему и существует лишь для абстрактного отделения мемоизации данных от мемоизации методов. Кто знает, может в дальнейших версиях React’a способы хранения данных будут изменяться, так как это очень похоже на наследие классовых компонентов.


ссылка на оригинал статьи https://habr.com/ru/articles/579242/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *