React useContext Hook(钩子)

React 上下文

React Context(上下文) 是一种全局管理状态的方法。

它可以与 useState 钩子一起使用,在独立嵌套的组件之间共享状态比单独使用 useState 更容易。


问题

状态应该由堆栈中需要访问状态的最高父组件持有。举例来说,我们有许多嵌套组件,而顶级和底部的组件需要访问状态。

那么要在没有上下文的情况下执行此操作,我们需要将状态作为 props 传递给每个嵌套组件。这被称为 "prop drilling"(state 通过 props 一层层传下去,传递到层级很深的子组件的过程。)。

实例:

通过一层一层的组件传递 "props":

  1. import { useState, useEffect } from "react";
  2. import ReactDOM from "react-dom";
  3. function Timer() {
  4. const [count, setCount] = useState(0);
  5. useEffect(() => {
  6. setTimeout(() => {
  7. setCount((count) => count + 1);
  8. }, 1000);
  9. });
  10. return <h2>I have rendered {count} times!</h2>;
  11. }
  12. ReactDOM.render(<Timer />, document.getElementById('root'));

即使组件 2-4 不需要状态,它们也必须传递状态,以便能够到达组件 5。


解决方法

解决方法就是创建 context 上下文。

创建 Context

要创建上下文,就必须导入 createContext 并将其初始化:

  1. import { useState, createContext } from "react";
  2. import ReactDOM from "react-dom";
  3. const UserContext = createContext()

接下来,我们将使用 Context(上下文),提供程序给需要状态上下文的组件树。

上下文提供

将子组件包含在上下文提供的范围内,并提供状态值。

  1. function Component1() {
  2. const [user, setUser] = useState("Jesse Hall");
  3. return (
  4. <UserContext.Provider value={user}>
  5. <h1>{`Hello ${user}!`}</h1>
  6. <Component2 user={user} />
  7. </UserContext.Provider>
  8. );
  9. }

现在,此树中的所有组件都可以访问用户上下文。

使用 useContext 钩子

为了在子组件中使用 Context 上下文,我们需要使用 useContext 钩子访问它。

首先,在 import 语句中包含 useContext

  1. import { useState, createContext, useContext } from "react";

然后,您可以访问所有组件中的用户上下文

  1. function Component5() {
  2. const user = useContext(UserContext);
  3. return (
  4. <>
  5. <h1>Component 5</h1>
  6. <h2>{`Hello ${user} again!`}</h2>
  7. </>
  8. );
  9. }

完整实例

下面是使用 React 上下文的完整示例:

  1. import { useState, createContext, useContext } from "react";
  2. import ReactDOM from "react-dom";
  3. const UserContext = createContext();
  4. function Component1() {
  5. const [user, setUser] = useState("Jesse Hall");
  6. return (
  7. <UserContext.Provider value={user}>
  8. <h1>{`Hello ${user}!`}</h1>
  9. <Component2 user={user} />
  10. </UserContext.Provider>
  11. );
  12. }
  13. function Component2() {
  14. return (
  15. <>
  16. <h2>Component 2</h2>
  17. <Component3 />
  18. </>
  19. );
  20. }
  21. function Component3() {
  22. return (
  23. <>
  24. <h2>Component 3</h2>
  25. <Component4 />
  26. </>
  27. );
  28. }
  29. function Component4() {
  30. return (
  31. <>
  32. <h2>Component 4</h2>
  33. <Component5 />
  34. </>
  35. );
  36. }
  37. function Component5() {
  38. const user = useContext(UserContext);
  39. return (
  40. <>
  41. <h2>Component 5</h2>
  42. <h3>{`Hello ${user} again!`}</h3>
  43. </>
  44. );
  45. }
  46. ReactDOM.render(<Component1 />, document.getElementById("root"));

分类导航