В чем разница между useMemo и useCallback

Ответ

useMemo и useCallback оба оптимизируют производительность, но решают разные задачи:

  • useMemo кэширует результат вычислений и возвращает его, пока зависимости не изменились.
    Пример:
    const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • useCallback кэширует саму функцию, а не её результат. Полезно для передачи стабильных колбэков дочерним компонентам.
    Пример:
    const memoizedCallback = useCallback(() => { doSomething(a, b) }, [a, b]);

Ключевое отличие:

  • useMemo — для значений,
  • useCallback — для функций.

Оба предотвращают лишние ререндеры, но только если зависимости остаются прежними.

Ответ 18+ 🔞

Ну ты посмотри, какие крючки React придумал, просто ёперный театр! Два брата-близнеца, useMemo и useCallback. Со стороны вроде одно и то же делают — оптимизация, кэширование, всё такое. А на деле, как два хуя с горы — похожи, но задачи разные, блядь.

Вот смотри, первый, useMemo — это такой запасливый мужик. Ему дали тяжёлую, ебучую работу посчитать, он её раз посчитал, записал результат на бумажку и суёт тебе эту бумажку каждый раз, когда ты просишь. Пока условия (a и b) не поменялись, он новую хуйню считать не будет, экономит силы. Чистая математика, блядь.

const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Видишь? Он тебе значение отдаёт. Результат этой computeExpensiveValue. Не саму функцию, а то, что она насчитала. Умный внатуре.

А вот его братан, useCallback — это тот ещё хитрожопый тип. Он функцию не вычисляет, он её запоминает. Как будто ты сказал коллеге: «Слушай, если что, звони мне вот с этого номера». И пока твой номер (a и b) не сменился, коллега будет звонить всегда по одному и тому же, старому номеру, а не искать тебя каждый раз по новому. Это чтобы дочерние компоненты не дергались почём зря, когда им колбэк передаёшь.

const memoizedCallback = useCallback(() => { doSomething(a, b) }, [a, b]);

Видишь разницу, а? useCallback возвращает тебе не число, не массив, а ту самую функцию, старую, закешированную. Новую не создаёт, пока зависимости те же.

Короче, суть проста до безобразия, как палка:

  • useMemo — это про значения. «Дай мне результат, но не пересчитывай, если можно».
  • useCallback — это про функции. «Дай мне ту же самую ссылку на функцию, а не новую каждый раз».

Оба, сука, молодцы, оба от лишних ререндеров спасают. Но работает эта магия только до тех пор, пока массив зависимостей (этот [a, b]) не накрылся медным тазом. Как только a или b поменялись — всё, приехали, пересчёт или новая функция, волнение ебать. Так что следи за зависимостями, а то оптимизация твоя в пизду улетит.