Ответ
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 поменялись — всё, приехали, пересчёт или новая функция, волнение ебать. Так что следи за зависимостями, а то оптимизация твоя в пизду улетит.