redux主要涉及到的仓库有:redux、redux-toolkit、redux-thunk、react-redux
- redux是JavaScript应用的状态容器,提供可预测的状态管理;
- redux-toolkit是redux的工具包,是官方推荐的编写Redux逻辑的方法;
- redux-thunk是redux的中间件, 使dispatch可以接受函数,赋予其执行异步操作的能力;
- react-redux为react的redux绑定库, 使react组件可以使用redux,且当 redux store发生变化时,可以自动更新react组件
1、安装依赖
npm i react-redux redux redux-thunk redux-persist
2、目录结构
// 目录结构
src
└───store
│ └───actions
│ │ │ index.js
│ │ │ xxx.js
│ └───reducers
│ │ │ index.js
│ │ │ xxx.js
│ │ action-types.js
│ │ index.js
│ index.js
3、状态管理示例
src/index.js 引入状态管理器
import React from "react";
import ReactDOM from "react-dom/client";
import Router from "./router";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { persistor, store } from "./store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Router />
</PersistGate>
</Provider>
);
src/store/index.js 创建状态管理器store
import { createStore, applyMiddleware } from "redux";
import reduxThunk from "redux-thunk";
import reducers from "./reducers";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
const persistConfig = {
key: "root",
storage: storage,
};
// 数据持久化 使用storage,reducers下的index集成多个state数据
const myPersistReducer = persistReducer(persistConfig, reducers);
export const store = createStore(myPersistReducer, applyMiddleware(reduxThunk));
export const persistor = persistStore(store);
src/store/actions/index.js 编写更改state数据的方法
// index.js
import {
login,
setUserToken,
setUserInfo,
resetUser,
} from "./login";
// 导出所有action方法
export { login, setUserToken, setUserInfo, resetUser };
// xxx.js(login.js)
import * as types from "../action-types";
import { loginAPI } from "@/api/login";
import { setToken, removeToken } from "@/utils/auth";
export const setUserToken = (token) => {
return {
type: types.USER_SET_TOKEN,
token,
};
};
export const setUserInfo = (userinfo) => {
return {
type: types.USER_SET_INFO,
userinfo,
};
};
export const resetUser = () => {
return {
type: types.USER_RESET_USER,
};
};
export const login = (data) => (dispatch) => {
return new Promise((resolve, reject) => {
loginAPI(data)
.then((response) => {
const { data, errmsg, errno } = response;
if (errno === 200) {
const token = data.token;
const userinfo = data.userinfo;
dispatch(setUserToken(token));
dispatch(setUserInfo(userinfo));
setToken(token);
resolve(response);
} else {
const msg = errmsg;
reject(msg);
}
})
.catch((error) => {
reject(error);
});
});
};
src/store/reducers/index.js 创建存储数据集成多个state
// index.js
import { combineReducers } from "redux";
import user from "./user";
// 导出所有数据到store中存储
export default combineReducers({
user,
});
// xxx.js(user.js)
import * as types from "../action-types";
const initUser = {
token: "",
userinfo: {},
};
export default function user(state = initUser, action) {
switch (action.type) {
case types.USER_SET_TOKEN:
return {
...state,
token: action.token,
};
case types.USER_SET_INFO:
return {
...state,
userinfo: action.userinfo,
};
case types.USER_RESET_USER:
return {};
default:
return state;
}
}
src/store/action-types.js 常量配置
// user_info 定义常量使用
export const USER_SET_TOKEN = "USER_SET_TOKEN";
export const USER_SET_INFO = "USER_SET_INFO";
export const USER_RESET_USER = "USER_RESET_USER";
组件内操作store存储的数据
import { useDispatch, useSelector } from "react-redux";
export default Login() {
const dispatch = useDispatch();
const { token } = useSelector((state) => state.user);
dispatch(login(data))
.then((res) => {
if (res.errno === 200) {
navigate("/product");
} else {
Toast.fail(res.msg);}
})
.catch((err) => {
Toast.fail(err);
});
}