redux在hooks里的用法(redux-toolkit)

644 阅读2分钟

redux的繁杂程度不必多说,容器和状态组件相分离,繁多的action以及reducer。redux官方为了简化这一操作推出了redux-toolkit

  1. 起步安装
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit

  1. 定义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
  1. 定义自定义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
  1. 定义相应的切片
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
  1. 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
  1. 在函数式组件里使用
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
  1. 官方网站

前端新手每日笔记-2