React Hooks:如何创建和更新 Context.Provider 入门 创建我们的 ContextOne 文件 创建我们的 App 文件 运行我们的示例 结论

2025-06-07

React Hooks:如何创建和更新 Context.Provider

入门

创建我们的 ContextOne 文件

创建我们的 App 文件

运行我们的示例

结论

如果你是第一次听说“React Hooks”,可以看看 React Conf 的介绍。非常值得一看!

我不会花太多时间解释新的 API,关于这一点,你可以去看看他们的文档。React 团队做了非常出色的工作,解释了所有原因以及他们是如何实现的。

入门

有了实际操作的例子,一切都会变得更好,让我们从以下例子开始:

$ mkdir react-hooks-contex-provider
$ cd react-hooks-contex-provider
$ yarn init -y
$ yarn add react@^16.7.0-alpha.0 react-dom@^16.7.0-alpha.0
$ yarn add parcel-bundler
Enter fullscreen mode Exit fullscreen mode

有了这个样板,我们就可以:

  • React alpha 版本,所有 hooksuse*可用
  • Parcel Bundler 运行我们的本地示例

让我们添加 HTML 文件:

$ touch index.html
Enter fullscreen mode Exit fullscreen mode

添加一些 HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>React Parcel</title>
</head>
<body>
  <div id="root"></div>
  <script src="./src/index.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

正如我们在 HTML 中看到的,我们有一个./src/index.js文件,让我们创建它:

$ mkdir src
$ touch src/index.js
Enter fullscreen mode Exit fullscreen mode

添加一些 JavaScript:

import * as React from "react";
import * as ReactDOM from "react-dom";

import { ContextOneProvider } from "./ContextOne";
import { App } from "./App";

function main(target, container) {
  ReactDOM.render(target, container);
}

main(
  <ContextOneProvider>
    <App />
  </ContextOneProvider>,
  document.getElementById("root")
);
Enter fullscreen mode Exit fullscreen mode

这里没什么不同。我们熟悉的ReactDOM.render渲染组件名为 ,App它被包裹在名为 的上下文中ContextOneProvider

创建我们的 ContextOne 文件

我们的后续行动./src/index.js可以是我们的./src/ContextOne.js,让我们创建它:

$ touch src/ContextOne.js
Enter fullscreen mode Exit fullscreen mode

并使用下面的代码片段:

import * as React from "react";

let ContextOne = React.createContext();

let initialState = {
  count: 10,
  currentColor: "#bada55"
};

let reducer = (state, action) => {
  switch (action.type) {
    case "reset":
      return initialState;
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    case "set-color":
      return { ...state, currentColor: action.payload };
  }
};

function ContextOneProvider(props) {
  // [A]
  let [state, dispatch] = React.useReducer(reducer, initialState);
  let value = { state, dispatch };


  // [B]
  return (
    <ContextOne.Provider value={value}>{props.children}</ContextOne.Provider>
  );
}

let ContextOneConsumer = ContextOne.Consumer;

// [C]
export { ContextOne, ContextOneProvider, ContextOneConsumer };

Enter fullscreen mode Exit fullscreen mode

这里有新面孔,是吧?90% 的代码都很熟悉,我们来检查一下[A][B][C]

  • [A]:我们在这里使用了新的 React Hooks API,名为useReducer。如果您熟悉 Redux,那么您已经知道它的工作原理。它将返回一个state对象和一个dispatch用于将更新发送到 store 状态的函数。我们将value使用这两个函数创建一个对象,并将其发送给我们的项目[B]
  • [B]:在这里,我们使用上下文提供程序来注入value对象,使其可供所有使用者使用。之前我们看到,我们使用它来包装我们的<App />./src/index.js这意味着 的所有子组件都<App />可以提取此上下文来使用。
  • [C]:乍一看,这个导出有点奇怪。我们导出的是 React 创建的默认上下文对象(ContextOne自定义提供程序),ContextOneProvider以及消费者键的别名ContextOneConsumer。要使用新的Reactk Hooks API(称为 useContext )来处理上下文,我们需要传递 React 创建的默认对象(第一个导出)。第二个导出ContextOneProvider是自定义提供程序,我们需要使用它来在应用上下文中注入所需的内容。最后一个导出ContextOneConsumer只是为了方便订阅上下文变化,这是 React 的一个稳定功能

创建我们的 App 文件

最后,但同样重要的是,让我们关注我们的./src/App.js文件:

$ touch src/App.js
Enter fullscreen mode Exit fullscreen mode

并粘贴一些 JavaScript:

import * as React from "react";

import { ContextOne } from "./ContextOne";

export function App() {
  // [A]
  let { state, dispatch } = React.useContext(ContextOne);

  // [B]
  React.useEffect(
    () => {
      document.body.style.backgroundColor = state.currentColor;
    },
    [state.currentColor]
  );

  // [C]
  let inc = () => dispatch({ type: "increment" });
  let dec = () => dispatch({ type: "decrement" });
  let reset = () => dispatch({ type: "reset" });
  let setColor = color => () => dispatch({ type: "set-color", payload: color });

  return (
    <React.Fragment>
      <div style={{ textAlign: "center" }}>
        <p>
          Current color is: <b>{state.currentColor}</b>
        </p>
        <p>
          Current count: <b>{state.count}</b>
        </p>
      </div>
      <div style={{ paddingTop: 40 }}>
        <p>Count controls:</p>
        <button onClick={inc}>Increment!</button>
        <button onClick={dec}>Decrement!</button>
      </div>
      <div>
        <p>Color controls:</p>
        <button onClick={setColor("green")}>Change to green!</button>
        <button onClick={setColor("papayawhip")}>Change to papayawhip!</button>
      </div>
      <div>
        <p>Reset changes:</p>
        <button onClick={reset}>Reset!</button>
      </div>
    </React.Fragment>
  );
}
Enter fullscreen mode Exit fullscreen mode

哇,现在怎么样?90% 的代码大家都很熟悉了,我们来看看剩下的 10%:

  • [A]:我们使用名为 useContext 的新 React Hooks API来使用我们的上下文(注意,我们导入了ContextOne由 React 创建的对象)。当提供程序更新时,此 Hook 将使用最新的上下文值触发重新渲染。
  • [B]:另一个名为 useEffect 的 React Hooks API。可以将效果视为从 React 纯函数式世界进入命令式世界的逃生舱。任何修改、订阅、计时器和其他副作用都可以使用此钩子来实现。作为第一个参数,我们传递一个包含效果的函数,用于更改主体背景颜色。作为第二个参数,我们传递一个数组,该数组告诉 React:“嘿,当这些 props/值发生变化时,就运行我的效果。”
  • [C]:普通的 JavaScript 箭头函数,但值得注意的是,我们使用dispatch上下文中的函数来更新我们的提供程序。

运行我们的示例

现在,我们已经到了真正的交易阶段,让我们运行我们的例子:

$ yarn parcel index.html
Enter fullscreen mode Exit fullscreen mode

您应该会看到类似这样的内容:

打开你的localhost:1234

结论

React Hooks API非常强大。Twitter上的社区正在🔥上。我们在 GitHub 上已经有很棒的示例

你觉得怎么样?你上瘾了吗?:P

文章来源:https://dev.to/oieduardorabelo/react-hooks-how-to-create-and-update-contextprovider-1f68
PREV
React Native:Como 组织了项目的 Estrutura geral do projeto Minha Filosofia sobre Componentes Organizando por “Área Funcional” Evite Aninhamento Profundo Fique Flexível Créditos ⭐️
NEXT
作为开发者,我最想改进的 5 个 YouTube 频道