上下文
- 全局变量是全局的上下文
- 上下文是局部的全局变量
如何使用useContext
- 使用
C=createContext(initial)
创建上下文 - 使用
<C.provider>
圈定作用域 - 在作用域内使用
useContext(C)
来使用上写文
代码演示
import React, { createContext, useState, useContext } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
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 rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
注意事项:useContext不是响应式的
- 你在另一个模块将C里面的值改变
- 另一个模块不会感知到这个变化
在Son子组件里,可以读到n,setN。注意n是它的上层组件里的数据,但是Son却可以读和写,就是因为使用了全局上下文。
它的作用机制是一个自顶向下,逐级通知的过程。在Son里setN,就会通知state,我要改变n,就会重新渲染App,App在执行的过程中发现我里边的n变了,就逐级通知,问:Baba组件你有没有用我的n,Baba说我没用。Baba又去问Son,Son发现自己用了这个n,那就跟着改变。这并不是一个响应式的。响应式的应该是发现n变了,去找使用n的组件,直接改变。