揭秘 React Hooks:useContext
React Hooks 改变了函数式组件的使用方式,提供了一种更简单的方法来封装用户界面中的状态行为和副作用。由于某些 Hooks 比其他 Hooks 更容易理解和使用,本系列文章将重点介绍那些不那么简单的 Hooks。
到目前为止,我们深入探讨了 useCallback、useMemo 和 useRef。本文将首先探讨prop 调用和context之间的区别,然后定义context 对象,解释如何使用 useContext() hook,以及如何优化其性能。
Prop 钻探与上下文
React 提供了一种数据流,父组件使用 props 与其子组件共享数据。这种数据追踪方式对于小型应用来说非常有效,然而,随着应用规模的扩大,你可能会发现自己需要将 prop 传递到多个组件层级。这被称为prop 钻取。
当 props 跨层传递时,识别数据在何处初始化以及何时实际使用会变得非常困难且繁琐。此外,重构代码可能会导致传递不必要的 props,或为一个 prop 使用多个名称(也就是 bug!)。
prop 钻取的替代方法是使用Context,这是一种简单而轻量的解决方案,它使我们能够跨组件访问数据,即使它们没有父子关系。
什么是上下文对象?
使用 API 创建上下文对象,createContext()
它由两个元素组成:
提供者:提供价值
消费者:消费价值
要创建上下文对象,您可以将其初始化为空或使用一个值:
const testContext = createContext();
您可以通过以下方式解构来访问其元素:
const { Provider, Consumer } = testContext;
如何使用提供程序?
Provider
上下文对象需要包裹组件树的父元素。这样,组件树下的每个组件都可以访问全局数据。查看下面<Provider>
的标签,它们使所有被包裹的组件都可以访问状态。现在,即使我们没有将状态作为 prop传递,name
组件<NameModifier />
及其<NamePrinter />
子元素也可以访问状态。name
name
const App = () => {
const { Provider } = testContext;
const [name, setTestName] = useState(“Milu”);
return (
<Provider value={{ name }}>
<NameModifier />
<NamePrinter />
</Provider>
);
};
如何使用 useContext() 访问我们的全局数据?
useContext ()钩子接受一个上下文对象(上面定义)并返回提供程序提供的当前值作为静态变量。
这里我们有我们的<NamePrinter />
组件(由上一节代码中的 Provider 标签包装),我们正在name
使用我们的userContext()
钩子来访问的值。
export const NamePrinter = () => {
const { name } = useContext(testContext);
return <div>My name is {name}!</div>
};
你注意到了吗?它
<NamePrinter />
没有接受任何 props 吗?而是使用useContext() hookname
来访问值。
我如何更新我的上下文?
您还可以通过您的提供商提供这些功能!
在下面的示例中,我创建了一个名为 的函数updateName()
,它允许你修改name
状态。如果你仔细查看组件<NameModifier />
,就会发现我updateName()
使用 useContext hook 访问该函数,并在每次输入发生变化时调用它。
那么性能如何呢?
使用useContext()的组件会在上下文对象中的值更新时重新渲染。你可能会遇到上下文中某个值频繁变化的情况,这可能会导致所有使用useContext() 的组件重新渲染,即使这个快速变化的值只在一小棵组件树中使用。
推荐的解决方案是拆分上下文。因此,如果您有浅色/深色主题,并且有一个切换开关可供选择,而这些开关与上下文共享的其他值相比,很可能不会频繁更改,那么您需要创建一个如下所示的“ThemeContext
和” 。AppContext
const App = ({ user, theme, themeToggle }) => {
return (
<ThemeProvider value={{ theme, themeToggle }}>
<AppContext value={{ user }}>
<HomePage />
</AppContext>
</ThemeProvider>
);
};
概括
使用context对象是prop 钻取的绝佳替代方案。它允许你访问全局数据,而无需将其作为 props 传递,并且它会订阅该数据,以便在数据发生变化时重新渲染。
上下文对象包含两个元素:Provider
和Consumer
。
该Provider
元素需要包装可以访问全局数据的组件树。
useContext ()钩子允许您从包装器下的组件树中的任何子组件访问全局数据Provider
。
为了避免不必要的重新渲染,请拆分上下文。即使用ThemeContext
和AppContext
。
我希望对useContext()的解释对您有所帮助,并且您将在未来的应用程序中应用这些新概念!
我每周都会发布新内容。下周末我们将探索不同的 React Hook。关注我的Twitter和Dev.to,及时获取最新动态!
鏂囩珷鏉ユ簮锛�https://dev.to/milu_franz/demystifying-react-hooks-usecontext-5g4a