useContext作用
Context
提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。Context
设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。
useContext使用
createContext
const P = createContext(defaultValue);
先使用 createContext
创建一个 Context
对象。
就能使用 useContext
订阅了这个 Context
对象。这个组件会从组件树中,离自身最近的上层 Provider
中读取到当前的 context
值。当未匹配到时,值为设置的默认值defaultValue
。
Provider
每个 Context
对象都会返回一个 Provider
React 组件,它允许消费组件订阅 context
的变化。
多个 Provider
也可以嵌套使用,里层的会覆盖外层的数据。
<P.Provider value={/* 值 */}>
...
</P.Provider>
useContext
useContext
接收一个 context 对象(React.createContext
的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <P.Provider value={}>
的 value 决定。
注意:useContext 的参数必须是 context 对象本身
// P Context 对象 由 createContext创建
const count = useContext(P);
多层级使用
import React, { createContext, useContext, useState } from "react";
// 创造一个上下文
const P = createContext(null);
// 创造一个上下文 带默认值
const B = createContext({ value: 3333, count: 12121 });
// 子组件
const Pa = () => {
// 获取 P--Context
const { count, setCount } = useContext(P);
const add = () => {
setCount((n) => n + 1);
};
return <div onClick={add}>pa==P==={count}</div>;
};
// 孙子组件
const Ba = () => {
// 获取 B--Context
const value = useContext(B);
return <div>Ba==B==={value.value}</div>;
};
// 孙子组件
const Bb = () => {
// 获取 P--Context
const count = useContext(P);
// 获取 B--Context
const value = useContext(B);
return (
<div>
Bb==B==={value.value},Bb==B===默认值==={value.count},<br />
Pb--P==={count.count},
</div>
);
};
// 子组件
const Pb = () => {
// 获取 P--Context
const { count, setCount } = useContext(P);
const add = () => {
setCount((n) => n + 1);
};
return (
<div>
<div onClick={add}>Pb==P==={count}</div>
{/* 加入新的 P--Context */}
<P.Provider value={{ count: 2222 }}>
<B.Provider value={{ value: 1111 }}>
<Ba></Ba>
<Bb></Bb>
</B.Provider>
</P.Provider>
</div>
);
};
// 顶级组件
const Home = (props) => {
const [count, setCount] = useState(0);
return (
<div>
<P.Provider value={{ count, setCount }}>
<Pa></Pa>
<Pb></Pb>
</P.Provider>
</div>
);
};
export default Home;
- 在组件树中
<P.Provider>
出现多次,订阅组件的Context
值,以上层最近的<P.Provider>
value 为准。 - 当组件树上层未使用
<B.Provider>
包裹,可直接使用useContext(B)
, 值为设置的默认值。 - 组件树中使用多个
Context.Provider
包裹,只需注意useContext()
传入的Context
对象,就能获取对应的值。