Согласно React doc, useMemo и useCallback помогают оптимизировать производительность, потому что сравнение между рендерингом работает правильно.
Насколько я понимаю, однако, всякий раз, когда родительский компонент перерисовывается, его дочерние компоненты также перерисовываются. Поскольку контекст реакции работает с провайдером, все подписчики контекста находятся под родительским провайдером. Таким образом, повторный рендеринг родительского провайдера, вероятно, также вызывает повторный рендеринг дочернего.
Заявление ниже React doc меня смущает. Кто-нибудь может это объяснить?
даже если MyApp потребуется повторная визуализация, компонентам, вызывающим useContext(AuthContext), не потребуется повторная визуализация.
Насколько я понимаю, однако, всякий раз, когда родительский компонент перерисовывается, его дочерние компоненты также перерисовываются.
Это верно по умолчанию, но React.memo можно использовать, чтобы пропустить повторный рендеринг дочернего элемента, если его свойства не изменились. Поэтому, если вы используете React.memo для повышения производительности, вам нужно убедиться, что ваше значение контекста не меняется все время, что сведет на нет преимущества React.memo.
Например, документация, на которую вы ссылаетесь, MyApp
возвращает следующее:
const MyApp = () => {
// ...
return (
<AuthContext.Provider value = {contextValue}>
<Page />
</AuthContext.Provider>
);
}
Предположим, что Page
реализовано примерно так:
import { memo } from 'react';
const Page = memo(() => {
return (
<ChildThatUsesContext />
)
})
const ChildThatUsesContext = () => {
const value = useContext(AuthContext);
// ... do stuff
}
Если MyApp
перерисовывается, а contextValue
не меняется, то и Page
, и ChildThatUsesContext
могут пропустить рендеринг.
Если MyApp
перерендерится, а contextValue
действительно изменится, то Page
сможет пропустить рендеринг, но ChildThatUsesContext
(и все его потомки) придется рендерить, потому что он вызвал useContext(AuthContext);
Таким образом, причина запоминать contextValue
состоит в том, чтобы чаще помещать нас в этот первый случай, когда все компоненты пропускают рендеринг, а не только Page
.
Ага, понятно. За кулисами есть React.memo.