Как закешировать вычисления?
Иногда полезно закешировать какие нибудь вычисления требующие больших вычислительных мощностей. Помочь в этом может хук useMemo
, он позволяет вам закешировать вычисления между несколькими рендерами, путём запоминания прошлого результата:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Этот код вызовет computeExpensiveValue(a, b)
. Но если зависимости [a, b]
не изменились с прошлого рендера, useMemo
пропустит повторный вызов и повторно использует значения, которые он вернул в прошлый раз.
Помните, что функция, передаваемая в useMemo
, выполняется во время рендера. Не стоит делать в ней что-то, что вы обычно не делаете во время рендера. Например, побочные эффекты выполняются в хуке useEffect
, а не в useMemo
.
Рассматриваете useMemo
, как оптимизацию производительности, но не стоит полагаться на неё на 100%. В будущем React сможет забыть
прошлые закешированные значения и провести перерасчёт на следующем рендере, например, для освобождения памяти, занятой компонентами вне экрана. Пишите ваш код так, чтобы он мог работать без useMemo
, и только тогда добавляйте оптимизацию производительности.
Также удобно, что useMemo
позволяет пропускать затратные повторные рендеры дочерних компонентов:
function Parent({ a, b }) {
// Рендерится повторно, только если `a` изменится:
const child1 = useMemo(() => <Child1 a={a} />, [a]);
// Рендерится повторно, только если `b` изменится:
const child2 = useMemo(() => <Child2 b={b} />, [b]);
return (
<>
{child1}
{child2}
</>
)
}
Обратите внимание, что этот подход не будет работать внутри циклов, так как вызовы хуков не могут быть помещены внутрь циклов. Но вы можете создать отдельный компонент для элемента списка, и вызвать useMemo
там.
Last updated
Was this helpful?