React useContext Hook
React 上下文
React 上下文是一种全局管理状态的方式。
它可以与 useState
Hook 结合使用,以便比单独使用 useState
更轻松地在深度嵌套的组件之间共享状态。
问题
状态应由堆栈中需要访问该状态的最高父组件持有。
为了说明这一点,我们有很多嵌套组件。堆栈顶部和底部的组件需要访问状态。
如果不使用上下文,我们需要将状态作为“props”传递给每个嵌套组件。这称为“属性穿透”。
示例
通过嵌套组件传递“props”
import { useState } from "react";
import ReactDOM from "react-dom/client";
function Component1() {
const [user, setUser] = useState("Jesse Hall");
return (
<>
<h1>{`Hello ${user}!`}</h1>
<Component2 user={user} />
</>
);
}
function Component2({ user }) {
return (
<>
<h1>Component 2</h1>
<Component3 user={user} />
</>
);
}
function Component3({ user }) {
return (
<>
<h1>Component 3</h1>
<Component4 user={user} />
</>
);
}
function Component4({ user }) {
return (
<>
<h1>Component 4</h1>
<Component5 user={user} />
</>
);
}
function Component5({ user }) {
return (
<>
<h1>Component 5</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Component1 />);
即使组件 2-4 不需要状态,它们也必须传递状态,以便它能够到达组件 5。
解决方案
解决方案是创建上下文。
创建上下文
要创建上下文,必须导入 createContext
并初始化它
import { useState, createContext } from "react";
import ReactDOM from "react-dom/client";
const UserContext = createContext()
接下来,我们将使用 Context Provider 来包装需要状态上下文的组件树。
上下文提供程序
将子组件包装在 Context Provider 中并提供状态值。
function Component1() {
const [user, setUser] = useState("Jesse Hall");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 user={user} />
</UserContext.Provider>
);
}
现在,此树中的所有组件都将能够访问用户上下文。
使用 useContext
Hook
为了在子组件中使用上下文,我们需要使用 useContext
Hook 访问它。
首先,在导入语句中包含 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/client";
const UserContext = createContext();
function Component1() {
const [user, setUser] = useState("Jesse Hall");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 />
</UserContext.Provider>
);
}
function Component2() {
return (
<>
<h1>Component 2</h1>
<Component3 />
</>
);
}
function Component3() {
return (
<>
<h1>Component 3</h1>
<Component4 />
</>
);
}
function Component4() {
return (
<>
<h1>Component 4</h1>
<Component5 />
</>
);
}
function Component5() {
const user = useContext(UserContext);
return (
<>
<h1>Component 5</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Component1 />);