React useContext Hook(钩子)
React 上下文
React Context(上下文) 是一种全局管理状态的方法。
它可以与 useState
钩子一起使用,在独立嵌套的组件之间共享状态比单独使用 useState
更容易。
问题
状态应该由堆栈中需要访问状态的最高父组件持有。举例来说,我们有许多嵌套组件,而顶级和底部的组件需要访问状态。
那么要在没有上下文的情况下执行此操作,我们需要将状态作为 props
传递给每个嵌套组件。这被称为 "prop drilling"(state
通过 props
一层层传下去,传递到层级很深的子组件的过程。)。
实例:
通过一层一层的组件传递 "props":
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
return <h2>I have rendered {count} times!</h2>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
即使组件 2-4 不需要状态,它们也必须传递状态,以便能够到达组件 5。
解决方法
解决方法就是创建 context 上下文。
创建 Context
要创建上下文,就必须导入 createContext
并将其初始化:
import { useState, createContext } from "react";
import ReactDOM from "react-dom";
const UserContext = createContext()
接下来,我们将使用 Context(上下文),提供程序给需要状态上下文的组件树。
上下文提供
将子组件包含在上下文提供的范围内,并提供状态值。
function Component1() {
const [user, setUser] = useState("Jesse Hall");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 user={user} />
</UserContext.Provider>
);
}
现在,此树中的所有组件都可以访问用户上下文。
使用 useContext 钩子
为了在子组件中使用 Context 上下文,我们需要使用 useContext
钩子访问它。
首先,在 import 语句中包含 useContext
import { useState, createContext, useContext } from "react";
然后,您可以访问所有组件中的用户上下文
function Component5() {
const user = useContext(UserContext);
return (
<>
<h1>Component 5</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
}
完整实例
下面是使用 React 上下文的完整示例:
import { useState, createContext, useContext } from "react";
import ReactDOM from "react-dom";
const UserContext = createContext();
function Component1() {
const [user, setUser] = useState("Jesse Hall");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 user={user} />
</UserContext.Provider>
);
}
function Component2() {
return (
<>
<h2>Component 2</h2>
<Component3 />
</>
);
}
function Component3() {
return (
<>
<h2>Component 3</h2>
<Component4 />
</>
);
}
function Component4() {
return (
<>
<h2>Component 4</h2>
<Component5 />
</>
);
}
function Component5() {
const user = useContext(UserContext);
return (
<>
<h2>Component 5</h2>
<h3>{`Hello ${user} again!`}</h3>
</>
);
}
ReactDOM.render(<Component1 />, document.getElementById("root"));