1.首先在react-ts项目中引入redux&react-redux
npm i --save redux react-redux
2.redux文件及目录建设
3.文件说明
Store.ts:为入口文件
reducers: 为多个reducer独立文件,并且每个reducer都设置自己的类型注解文件
代码展示如下:
//Store.ts
/**
rtk的configureStore集成了redux中的combineReducers,createStore,middleware以及默认支持reduxDevTools;
*/
import { configureStore } from "@reduxjs/toolkit";
//reducer引入
import CollapsedReducer from "./reducers/collapsed/CollapsedReducer";
const store = configureStore({
reducer:CollapsedReducer
});
export default store;
/**
* returnType:可以获取返回值的类型,使代码更具可维护性和可读性,
* 特别是在处理复杂的函数类型时,可以减少手动定义类型的工作,
* 同时增加了代码的类型安全性。它在编写高度类型化的代码或使用泛型函数时特别有用。
* */
export type AppDispatch = typeof store.dispatch; //获取修改方法
export type RootState = ReturnType; //获取设置的状态变量
//CollapsedReducer.ts
/**
PayloadAction:是 Redux Toolkit 中的一个类型,它用于定义 action 的结构以及传递给 reducer 的数据
**/
import { createSlice ,PayloadAction} from "@reduxjs/toolkit";
import { CollapsedState } from "./interface";
const initialState:CollapsedState = {
isCollapsed: false,
}
//createSlice:创建切片对象
const CollapsedReducerSlice = createSlice({
name:"CollapsedReducer", //唯一标识
initialState, //初始化状态数据
reducers:{ //1.定义reducers
//2.定义reducer更新状态数据的函数 ,setisCollapsed方法在后期组件中执行dispatch时是作为action函数的函数名去使用
setisCollapsed(state,{ payload }: PayloadAction){ //传入两个参数1state(代理的proxy对象),一个是action
console.log(state,"state");
console.log(payload,"payload");
state.isCollapsed = payload.isCollapsed
}
}
})
export const {
setisCollapsed
} = CollapsedReducerSlice.actions ;
export default CollapsedReducerSlice.reducer;
//interface.ts
export interface CollapsedState{
isCollapsed:boolean
}
关于定义hooks.ts文件的初衷:
因为当我准备在组件中使用cosnt isCollapsed = useSelector((state)=>state.isCollapsed)时会出现报错警告:'state' is of type 'unknown';
这个错误信息 "'state' 的类型为 'unknown'" 表示 TypeScript 无法推断你的 Redux 存储中的状态的类型。这可能是因为你没有正确定义 Redux 状态和 reducer 的类型。
所以最后的解决方案就是对使用状态就行类型注解并
//hooks.ts
import { TypedUseSelectorHook, useSelector,useDispatch } from 'react-redux';
import {AppDispatch, RootState } from "./Store"; // 导入你的 RootState
/**
* TypedUseSelectorHook:可以·提高代码维护与可读性减少重复类型注解
* RootState:是数据类型
* */
export const useAppSelector: TypedUseSelectorHook = useSelector; //全局使用useAppSelector
export const useAppDispatch: () => AppDispatch = useDispatch;
~~~~~~~~上述就对redux完成配置~~~~~~~
组件使用:这里为了简单演示将两个组件代码写在了一起,组件1&组件2
//组件1
import {useAppSelector} from "../../redux/hooks";
import {shallowEqual} from "react-redux";
/***
shallowEqual:在组件决定是否被渲染之前,会进行一次浅比较如果该组件依赖的state并没有被更改,不进行渲染
*/
function SideMenu() {
//获取store值
const isCollapsed = useAppSelector(state => state,shallowEqual);
return(
{isCollapsed.isCollapsed}
)
}
//组件2
import { Button } from 'antd';
import {useAppDispatch,useAppSelector} from "../../redux/hooks";
import {setisCollapsed} from "../../redux/reducers/collapsed/CollapsedReducer";
import {shallowEqual} from "react-redux";
function TopHeader(){
const dispatch = useAppDispatch();
const { isCollapsed } = useAppSelector(state => state,shallowEqual);
return(
: }
onClick={() => {
console.log("111",!isCollapsed)
dispatch(setisCollapsed({ isCollapsed: !isCollapsed }));
}}
)
}
最后千万切记要在项目根节点中设置Provider包裹全局使用store
<><>