redux的繁杂程度不必多说,容器和状态组件相分离,繁多的action以及reducer。redux官方为了简化这一操作推出了redux-toolkit
- 起步安装
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit
- 定义store/index.tsx
// 和老版redux不同
import { configureStore } from '@reduxjs/toolkit'
// reducer里面装的是各个文件导出的切片reducer之后再讲
export const store = configureStore({
reducer: {},
})
// 利用ts的内置类型获取state对象的返回值
export type RootState = ReturnType<typeof store.getState>
// 这是dispatch的类型
export type AppDispatch = typeof store.dispatch
- 定义自定义hook(为了方便)
// hooks/toolKit.ts
// 引入redux的内置hook
import { useDispatch, useSelector } from "react-redux"
import type { TypedUseSelectorHook } from "react-redux"
import type { RootState, AppDispatch } from "./store"
// 将内置hook赋值给自定义hook,这样就不需要一直在所有函数式组件里去声明类型
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
- 定义相应的切片
import { createSlice } from "@reduxjs/toolkit"
import { MenuItem, routes } from "../router/routes"
// 工具包自己提供的actionType
import type { PayloadAction } from "@reduxjs/toolkit"
// initstate
const initialState: MenuItem = routes
// 每一个切片管理一个数据源
// 切片name,初始状态,处理函数
export const menuSlice = createSlice({
name: "menu",
initialState,
reducers: {
// 和老版redux不同的是因为经过immer处理可以直接使用push,unshift等方法
addMenu(state, action: PayloadAction<MenuItem[number]>) {
state.unshift(action.payload)
}
}
})
// 暴露切片和action
export const { addMenu } = menuSlice.actions
export default menuSlice.reducer
- index.ts里设置切片别名
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './test'
import menuReducer from './menu'
//@ts-ignore
export const store: any = configureStore({
reducer: {
count: counterReducer,
menuList: menuReducer // 设置切片别名
}
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
- 在函数式组件里使用
import { useAppDispatch, useAppSelector } from '../hooks'
// 引入自定义hook和导出的action即可
import { addMenu } from '../store/menu'
const Test = ()=>{
// state即为整个状态对象,返回之前定义的别名即可,state不需要定义类型因为我们
// 在自定义hook里已经定义过
const list = useAppSelector((state) => state.menuList)
const dispatch = useAppDispatch()
const addDispatch = (padLoad: MenuItem[number]) => {
// 直接通过dispatch调用action即可
dispatch(addMenu(padLoad))
}
return (
<>
<Button type="primary" className='rounted-md' onClick={addDispatch(data)} >
新增
</Button>
</>
)
}
export default Test
前端新手每日笔记-2