使用useContext与useReducer来代替Redux
以下代码使用了TypeScript
首先是入口文件,一个父级Color
组件包裹两个子级组件,没啥好说的。
//index.tsx
import React from "react";
import ReactDOM from "react-dom";
import Color from "./Color";
import ShowArea from "./ShowArea";
import Btns from "./Btns";
ReactDOM.render(
<Color>
<ShowArea></ShowArea>
<Btns></Btns>
</Color>,
document.getElementById("root")
);
接下来是Color.tsx
组件,父级组件,也是代码的核心,我们一步一步来看。
- 首先,使用
createContext
创建了一个context
,初始默认值为空。 - 定义
reducer
函数要使用的常量UPDATE_COLOR
,用于更新字体颜色 - 同时,定义一个接口
IColorContext
用来描述ColorContext
- 接下来创建
reducer
函数,使用过redux
应该知道reducer
函数的使用方法 - 最后定义描述
props
的接口IProps
接下来就是Color.tsx
组件内部了
- 首先,使用数组解构的方式来获得
useReducer
的返回值,命名为color
和dispatch
函数 - 其次使用
ColorContext
的Provider
组件来向子孙元素传递color
和dispatch
//Color.tsx
import React, { createContext, useReducer, ReactElement } from "react";
export const ColorContext = createContext({});
export const UPDATE_COLOR = "updateColor";
export interface IColorContext {
color: string;
dispatch: Function;
}
const reducer = (state: string, action: { type: string; color: string }) => {
switch (action.type) {
case UPDATE_COLOR:
return action.color;
default:
return state;
}
};
interface IProps {
children: ReactElement[];
}
const Color = (props: IProps) => {
const [color, dispatch] = useReducer(reducer, "blue");
return (
<div>
<ColorContext.Provider value={{ color, dispatch }}>
{props.children}
</ColorContext.Provider>
</div>
);
};
export default Color;
然后就是子组件ShowArea.tsx
import
父组件Color.tsx
抛出的ColorContext
与接口IColorContext
- 使用对象解构的方式来获得
useContext
的返回值,命名为color
(此处需要使用TS的类型断言来描述useContext
的返回值)
//ShowArea.tsx
import React, { useContext } from "react";
import { ColorContext, IColorContext } from "./Color";
const ShowArea = () => {
const { color } = useContext(ColorContext) as IColorContext;
return <div style={{ color }}>wocao</div>;
};
export default ShowArea;
最后是来改变字体颜色的子组件Btns.tsx
import
父组件抛出的Context
对象ColorContext
、接口IColorContext
、常量UPDATE_COLOR
- 使用对象解构的方式从
useContext
中解构出dispatch
函数(此处也需要使用TS的类型断言) - 调用
dispatch
函数来更改字体颜色
//Btns.tsx
import React, { useContext } from "react";
import { ColorContext, IColorContext, UPDATE_COLOR } from "./Color";
const Btns = () => {
const { dispatch } = useContext(ColorContext) as IColorContext;
return (
<div>
<button onClick={() => dispatch({ type: UPDATE_COLOR, color: "yellow" })}>
yellow
</button>
<button onClick={() => dispatch({ type: UPDATE_COLOR, color: "red" })}>
red
</button>
</div>
);
};
export default Btns;
大功告成!