是否需要 useMemo 通过 reactjs 中的上下文 API 来管理状态?



我试图理解这篇(主要是非常有用的(文章,它描述了如何使用 react 的上下文 API 来管理应用程序级状态。对于简单应用程序(在本例中为基本计数器应用程序(,它使用以下解决方案:

const CountContext = React.createContext()
function CountProvider(props) {
const [count, setCount] = React.useState(0)
const value = React.useMemo(() => [count, setCount], [count])
return <CountContext.Provider value={value} {...props} />
}

提供上下文,然后是可以在组件树下方某处的组件中使用的以下钩子:

function useCount() {
const context = React.useContext(CountContext)
if (!context) {
throw new Error(`useCount must be used within a CountProvider`)
}
return context
}

我的问题:

我正在努力理解为什么这里需要useMemo钩子。这里不涉及特别繁重的计算,所以我不确定我们为什么要记住这些值。如果上下文提供程序如下所示,这是否也同样有效:

function CountProvider(props) {
const [count, setCount] = React.useState(0)
return <CountContext.Provider value={value} {...props} />
}

我觉得我可能错过了什么!!

有一个非常简单的理论来解释为什么你应该使用useMemo来记住传递给Context Provider的值。当您将值传递给Context Provider时,可以作为对象或数组,如下所示:

return <CountContext.Provider value={{state, setCount}} {...props} />

return <CountContext.Provider value={[state, setCount]} {...props} />

本质上发生的情况是,每次CountProvider组件重新呈现对对象或数组的新引用时,都会作为值传递给CountContext.Provider,因此即使实际值可能没有更改,Context 使用者也会重新呈现,因为该值的引用检查失败。

现在,您可能需要也可能不需要useMemo,具体取决于ContextProvider中的逻辑。例如,在您的情况下,CountContext只是使用一种状态,即 count 并将其传递给子元素,如果CountContext是顶级元素之一,除了计数更改之外不会重新呈现,那么在这种情况下,无论您是否使用useMemo都没有区别,因为来自useMemo的返回值的引用也会在计数更改时更新

但是,如果您有某些父项要CountProvider这可能会导致CountProvider重新渲染,那么记住上下文值useMemo会派上用场,以避免重新渲染所有上下文使用者

调用 setCount 将始终重新渲染组件

我相信调用 setCount 将始终重新渲染,即使将相同的值传递给函数。

但是这条线

const value = React.useMemo(() => [count, setCount], [count])

将停止调用 setCount,除非计数有不同的值。从而减少重新渲染并提高性能。

您可以通过在里面放一个日志并查看组件在有和没有useMemo的情况下如何呈现来测试这个理论。

React.useMemo

从来都不是必需的,因为它是一种性能优化。

如果您不使用 useMemo,它会触发不必要的重新渲染的想法是错误的。React 仅在组件树上的某个位置的状态更改后重新渲染组件。

以下是不会导致不必要的重新渲染的证据: https://codesandbox.io/s/stupefied-franklin-5jf5ke?file=/src/App.tsx

唯一的例外是当组件包装在React.memo()中时。在这种情况下,对道具或传递给 Context.Provider 的值useMemo可以防止不必要的重新渲染。

将上下文的值包装在useMemo中是一种不好的做法吗?不,我认为不是,特别是如果您在其他钩子的依赖项数组中使用该上下文,或者将其提供给记忆组件React.memo()

相关内容

  • 没有找到相关文章

最新更新