快速添加 Redux 到 Ts APP

整个 redux 采用功能进行划分数据数据流, 所以创建目录一般在 src/features/功能名称 下, 然后将 reducer 导出到 store 中进行管理.

安装依赖

在新项目中安装依赖

1
npx create-react-app my-app --template redux-typescript

已有项目安装依赖

1
2
yarn add react-redux @reduxjs/toolkit
yarn add -D @types/react-redux

修改主页内容支持 redux

修改 index.html 增加内容

1
2
import { Provider } from "react-redux";
import { store } from "./store";
1
2
3
<Provider store={store}>
<App />
</Provider>

构建数据管理模块 Slice

src/features/light/lightSlice.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { createSlice } from "@reduxjs/toolkit";

export const lightSlice = createSlice({
// 名称
name: "light",

// 初始化属性数据
initialState: { red: 1, yellow: 0, green: 0 },

// 定义属性数据操作方法
reducers: {
setState: (state, action) => {
const { red, yellow, green } = action.payload;

state.red = red;
state.yellow = yellow;
state.green = green;
},
},
});

export const { setState } = lightSlice.actions;

// 注意 reducer 是单数
export default lightSlice.reducer;

与数据管理器交互

src/features/light/Light.tsx

注意: 和 js 不同, ts 在包含 React 组件的文件要以 tsx 作为文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import React, { useState } from "react";

import { useAppSelector, useAppDispatch } from "../hook";
import { setState } from "./lightSlice";

function randLight() {
const rand = Math.floor(Math.random() * 3);
let red: number = 0,
yellow: number = 0,
green: number = 0;

if (rand === 0) {
red = 1;
}
if (rand === 1) {
yellow = 1;
}
if (rand === 2) {
green = 1;
}

return { red, yellow, green };
}

export default function Light() {
const { red, green, yellow } = useAppSelector((state) => state.light);
const dispatch = useAppDispatch();

return (
<div>
<span>
green: {green} red: {red} yellow: {yellow}
</span>
<button aria-label="change light color" onClick={() => dispatch(setState(randLight()))}>
Change Color
</button>
</div>
);
}

构建数据中心 store

src/store.ts

假设功能名称为 light

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { configureStore } from "@reduxjs/toolkit";

import { lightSlice } from "./light/lightSlice";

export const store = configureStore({
reducer: {
light: lightSlice.reducer,
},
});

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

src/hook.ts

1
2
3
4
5
6
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

参考资料

Donate - Support to make this site better.
捐助 - 支持我让我做得更好.