共计 2573 个字符,预计需要花费 7 分钟才能阅读完成。
想阅读更多优质文章请猛戳 GitHub 博客, 一年百来篇优质文章等着你!
所有这些新的 React Hook 之间都有一个宗旨:就是为了使函数组件像类组件一样强大。
useContext
hook 与其它几个有点不一样,但它在特定场景下还是很有用的。
React 的 Context API
是一种在应用程序中深入传递数据的方法,而无需手动一个一个在多个父子孙之间传递 prop
。当咱们需要的只是传递数据时,它可以作为像 Redux
这样的工具的一个很好的替代。
使用 Context
, 首先顶层先声明 Provier
组件,并声明 value
属性,接着在后代组件中声明 Consumer
组件,这个 Consumer
子组件,只能是唯一的一个函数,函数参数即是 Context
的负载。如果有多个 Context
,Provider
和 Consumer
任意的顺序嵌套即可。
此外我们还可以针对任意一个 Context
使用 contextType
来简化对这个 Context
负载的获取。但在一个组件中,即使消费多个 Context
,contextType
也只能指向其中一个。
在 Hooks
环境中,依旧可以使用 Consumer
,但是 ContextType
作为类静态成员肯定是用不了。Hooks 提供了 useContext
, 不但解决了 Consumer
难用的问题同时也解决了 contextType
只能使用一个 context
的问题。
标准方式
使用 API 的典型方法如下所示:
import React from "react";
import ReactDOM from "react-dom";
// 创建 Context
const NumberContext = React.createContext();
// 它返回一个具有两个值的对象
// {Provider, Consumer}
function App() {
// 使用 Provider 为所有子孙代提供 value 值
return (<NumberContext.Provider value={42}>
<div>
<Display />
</div>
</NumberContext.Provider>
);
}
function Display() {
// 使用 Consumer 从上下文中获取 value
return (
<NumberContext.Consumer>
{value => <div>The answer is {value}.</div>}
</NumberContext.Consumer>
);
}
ReactDOM.render(<App />, document.querySelector("#root"));
可以 CodeSandbox 上看看运行效果。
使用 useContext 方式
使用 useContext
hook 来重写上面的示例
import React, {useContext} from 'react';
// ...
function Display() {const value = useContext(NumberContext);
return <div>The answer is {value}.</div>;
}
调用 useContext
,传入从React.createContext
获取的上下文对象。
唯一需要注意 的是你必须将整个上下文对象传递给 useContext
– 而不仅仅是Consumer
,当然如果忘记了,React
会给出警告。
嵌套的 Consumers
你可能遇到这样的情况,咱们的组件需要从多个父上下文中接收数据,从而导致这样的代码
function HeaderBar() {
return (
<CurrentUser.Consumer>
{user =>
<Notifications.Consumer>
{notifications =>
<header>
Welcome back, {user.name}!
You have {notifications.length} notifications.
</header>
}
}
</CurrentUser.Consumer>
);
}
这种大量嵌套只是为了接收两个值。下面是使用 useContext
时的效果:
function HeaderBar() {const user = useContext(CurrentUser);
const notifications = useContext(Notifications);
return (
<header>
Welcome back, {user.name}!
You have {notifications.length} notifications.
</header>
);
}
总结
useContext
接收一个 context
对象(React.createContext
的返回值)并返回该 context
的当前值。当前的 context
值由上层组件中距离当前组件最近的 <CountContext.Provider>
的 value
prop 决定。
当组件上层最近的 <CountContext.Provider>
更新时,该 Hook 会触发重渲染,并使用最新传递给 CountContext provider
的 context value
值。
别忘记 useContext
的参数必须是 context
对象本身:
- 正确:useContext(MyContext)
- 错误:useContext(MyContext.Consumer)
- 错误:useContext(MyContext.Provider)
调用了 useContext
的组件总会在 context
值变化时重新渲染。如果重渲染组件的开销较大,你可以 通过使用 memoization
来优化。
代码部署后可能存在的 BUG 没法实时知道,事后为了解决这些 BUG,花了大量的时间进行 log 调试,这边顺便给大家推荐一个好用的 BUG 监控工具 Fundebug。
参考:
https://daveceddia.com/usecon…
交流
阿里云最近在做活动,低至 2 折,有兴趣可以看看:https://promotion.aliyun.com/…
干货系列文章汇总如下,觉得不错点个 Star,欢迎 加群 互相学习。
https://github.com/qq44924588…
我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复 福利,即可看到福利,你懂的。