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
有了这个样板,我们就可以:
- React alpha 版本,所有 hooks
use*
可用 - Parcel Bundler 运行我们的本地示例
让我们添加 HTML 文件:
$ touch index.html
添加一些 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>
正如我们在 HTML 中看到的,我们有一个./src/index.js
文件,让我们创建它:
$ mkdir src
$ touch src/index.js
添加一些 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")
);
这里没什么不同。我们熟悉的ReactDOM.render
渲染组件名为 ,App
它被包裹在名为 的上下文中ContextOneProvider
。
创建我们的 ContextOne 文件
我们的后续行动./src/index.js
可以是我们的./src/ContextOne.js
,让我们创建它:
$ touch src/ContextOne.js
并使用下面的代码片段:
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 };
这里有新面孔,是吧?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
并粘贴一些 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>
);
}
哇,现在怎么样?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
您应该会看到类似这样的内容:
打开你的localhost:1234
:
结论
React Hooks API非常强大。Twitter上的社区正在🔥上。我们在 GitHub 上已经有很棒的示例。
你觉得怎么样?你上瘾了吗?:P
文章来源:https://dev.to/oieduardorabelo/react-hooks-how-to-create-and-update-contextprovider-1f68