#javascript #reactjs #memoization #react-usememo
Вопрос:
Я использую React с крючками. У меня есть дорогая функция, которую я хотел бы запомнить.
Я знаю, что React поставляется с useMemo (), но значения, которые мне нужно запомнить, вычисляются один раз, каждое, при первом рендеринге. Таким образом, нет смысла запоминать в первом рендеринге, но запоминание в будущих рендерах было бы полезно.
Я прочитал документацию useMemo (), но она не дает однозначного ответа, поэтому: сохраняются ли значения, сохраненные в useMemo (), при повторной визуализации компонента, вызывающего useMemo?
Как я могу постоянно запоминать различные рендеры компонента React?
Комментарии:
1. извините, ваш вариант использования немного неясен, не могли бы вы уточнить? useMemo работает с несколькими повторными отправками
2. Нужно ли вычислять разные значения для каждого экземпляра компонента или только один раз?
3. @gmoniava Мне нужно вычислить значение, это медленно. Последующие запуски функции компонентов (я использую хуки, а не классы) должны получить доступ к результату вычисления.
4. @CertainPerformance Я не думаю, что у компонентов hook есть экземпляры — это просто выполняемые функции, верно?
5. Например , если у вас есть
<div><TheExpensiveComponent /><TheExpensiveComponent /></div>
, вам нужно будет сначала выполнить расчет дважды или только один раз? Или в данный момент отображается только один?
Ответ №1:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Допустим, приведенная выше строка кода находится внутри ComponentA
. Теперь, предполагая, что это ComponentA
не было размонтировано, затем memoizedValue
сохраняется при повторной визуализации, учитывая также, что зависимости ( a
, b
) не меняются при повторной визуализации.
Также в документах react говорится, что в будущем react может иногда решить забыть запомнившееся значение, поэтому его следует использовать для оптимизации, а не в качестве семантической гарантии.
Комментарии:
1. Я думаю, что неясно, когда крючок React считается «размонтированным»? Не реагирует ли он просто повторно запускать функцию компонентов всякий раз, когда это необходимо? Я хочу сохранить данные в разных запусках компонента.
2. @mikemaccana Говорит, что вы выполняете рендеринг
ComponentA
на одном рендере, и в следующий раз, когда вы будете отображать null вместо него, это один из случаев, когдаComponentA
считается размонтированным. Подробнее о согласовании и жизненном цикле React читайте здесь.3. Спасибо @gmoniava! Я видел , как reactjs.org/docs/reconciliation.html но в примерах используются только компоненты на основе классов, поэтому я не уверен, как/применимо ли это к крючкам.
4. @mikemaccana это также относится к крючкам
5. Я думаю, чего я не понимаю, так это того, что после рендеринга функция компонента hook вернулась. Как может что-то, хранящееся в
useMemo
, сохраняться после того, как функция вернулась? Я понимаю закрытие, использует ли React их для хранения ссылок на значения, хранящиеся вuseMemo
?
Ответ №2:
Для этого вам нужно использовать способ хранения значения вне компонента, например, поставщика и контекста. Для этого обратитесь к официальной документации React: https://reactjs.org/docs/context.html
Моя личная рекомендация-использовать Redux для React. Вот ваша официальная документация: https://redux.js.org/ Это очень часто используется для профессиональных решений, которым необходимо хранить глобальное состояние или данные для вашего приложения.
Вам нужно знать, что функция useMemo всегда связана с жизненным циклом компонента.