Должен ли я обернуть все функции, которые определены в компоненте в useCallback?
Насколько я знаю, функции, которые определены в функциональном компоненте React, восстанавливаются всякий раз, когда компонент перерисовывается. Поскольку useCallback может быть вызван конкретными зависимостями, это предотвращает ненужную регенерацию этих функций. Должен ли я обернуть каждый из них в useCallback и передать соответствующие зависимости?
import React from 'react'
const Comp = () => {
const fn1 = useCallback(
()=>{
// do something
}, [dependency1])
const fn2 = useCallback(
()=>{
// do something
}, [dependency2])
return (
//something
)
}
2 ответа
useCallback
поможет избежать регенерации функций при перерисовке функционального компонента. Однако разница в производительности, вызванная восстановлением функций, невелика.
Использование useCallback должно быть предпочтительным в следующих случаях
Если вы передаете функцию дочернему компоненту в качестве реквизита, и дочерний компонент часто не нуждается в повторном рендеринге, кроме случаев, когда определенное изменение реквизита использует useCallback, что может препятствовать определенным повторным визуализациям. Однако, если вы указали сложность, и вам нужно передать несколько таких функций детям в качестве реквизита, лучше перейти к
useReducer
вместоuseState
и передатьdispatch
метод для дочерних компонентовВы указываете функцию как зависимость от
useEffect
, В таком случае вы должны убедиться, что функция не воссоздается при каждом рендере илиuseEffect
будет срабатывать при каждом рендере.
В целом решение использовать useCallback
должно быть сделано разумно, а не вслепую, так как вы можете просто переусердствовать преимущество, предлагаемое useCallback
и в конечном итоге ухудшить производительность с useCallback
также запомнит функции, и часто изменяющаяся зависимость в любом случае может понадобиться для воссоздания функции.
Просто добавьте еще один случай к приведенному выше ответу. Иногда у вас может быть функция с тяжелыми вычислениями, и вы, вероятно, не хотите, чтобы она вычисляла результат на каждом рендере, поэтому в этом случае вы также должны использовать
useCallback