React教程,Context的两种消费方式,use和useContext
发布于 作者:苏南大叔 来源:程序如此灵动~
再次重新审视React
的上下文context
的使用方式,视角主要集中于获取上下文的值的两种方式。一种方式是useContext()
,另外一种方式是use
。这两种使用方式,究竟有什么相同和不同之处呢?
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0
,create-react-app@5.0.1
,react@19.0.0
。本文试图对比React
上下文的两种获取方式。
前文回顾
第一篇文章,主要讲述的是类组件和函数组件中,使用上下文的不同方式。
第二篇文章,讲述在函数组件中,createContext
的初始值和Provider
里的value
提供值之间的关系。
本文是第三篇文章,主要讲述在【函数组件】中,消费context
的两种方式:use()
和useContext()
。
useContext / use 相同之处
测试代码如下:
import { createContext, use, useContext } from "react";
const sunanContext = createContext("苏南大叔,初始值");
const MyUse = () => {
const sn = use(sunanContext);
const sn2 = useContext(sunanContext);
return (
<>
<div>
<b>use:</b>
{sn}
</div>
<div>
<b>useContext:</b>
{sn2}
</div>
</>
);
};
const App = () => {
return (
<>
<MyUse />
<sunanContext.Provider value="uncle sunan,覆盖值">
<MyUse />
</sunanContext.Provider>
</>
);
};
export default App;
<Context.Provider value=""></Context.Provider>
,可以提供一个新的覆盖值,把通过createContext()
定义的初始值给覆盖掉。
useContext / use 区别之处
上面的例子里面,useContext
和use
看起来是一样的效果。但是,下面的例子里面就有区别了。useContext
是钩子,它必须用在函数组件里面的顶层。而use
是react
的高阶api
,可以用在其它的地方,比如if
语句里面。
import { createContext, use, useContext } from "react";
const sunanContext = createContext("");
const MyUse2 = ({ su }) => {
if (su) {
const sn = use(sunanContext);
return <h3>{sn}</h3>;
}
return <div>没有权限</div>;
};
const App = () => {
return (
<>
<sunanContext.Provider value="uncle sunan,覆盖值">
<MyUse2 />
<MyUse2 su={true} />
</sunanContext.Provider>
</>
);
};
export default App;
然而,如果把上面的
const sn = use(sunanContext);
换成:
const sn = useContext(sunanContext);
后者会报错如下:
React Hook "useContext" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?
结语
更多苏南大叔的React
经验文章,请点击:


