React.useContext就是一个局部的全局上下文,因为必须在C.Procider区域内的组件才能使用。出了这个范围就用不了了。
const C=createContext(null) // 1. 创建一个全局上下文对象C
function App(){
const [n,setN]=useState(0)
return (
<C.Provider value={{n,setN}}> // 2. 用C.Provider圈定作用域,传value
<Baba /> // 全写:{{n:n,setN:setN}}
</C.Provider>
)
}
function Baba(){
return (
<div>
我是爸爸
<Son />
</div>
)
}
function Son(){
const {n,setN}=useContext(C) // 3. 使用上下文C,拿到读写接口
const onClick=()=>{
setN(i=>i+1) // 写
}
return (
<div>
我是儿子 n:{n} // 读
<button onClick={onClick}>+1</button>
</div>
)
}
const C=createContext(null)创建一个全局上下文对象C,一般初始化为null- 用
<C.Provider>标签圈定作用域。传一个value属性,把要共享出去的读写接口以对象的形式传给value。value={{n,setN}}最外层{}表示里边是JS代码,里层{}表示是对象。在这对标签里边的所有组件(包括各层嵌套的所有子组件),就都可以使用C提供的读写接口了。 - Son组件要使用这个读写接口,就用
const {n,setN}=useContext(C),注意得到的是对象。而且要在C的作用域内的组件才能使用。
在Son子组件里,就可以读到n,setN。注意n是它的上层组件里的数据,但是Son却可以读和写,就是因为使用了全局上下文。
它的作用机制是一个从上到下的,逐级通知的过程。在Son里setN,就会通知state,我要改变n,就会重新渲染App,App在执行的过程中发现我里边的n变了,就逐级通知,问:Baba组件你有没有用我的n,Baba说我没用。Baba又去问Son,Son发现自己用了这个n,那就跟着改变。这并不是一个响应式的。响应式的应该是发现n变了,去找使用n的组件,直接改变。