10分钟快速上手Redux-toolkit

@reduxjs/toolkit

这是React官网推荐的Redux公共状态管理工具

官网地址: cn.redux.js.org/introductio...

Demo GIt: gitee.com/tcwty123/re... 分支: @reduxjs/toolkit

相比于最原始的Redux,redux toolkit最大的特点是:

基于切片机制,把reducer和actionCreator混合在一起了,并且内部集成了immer 不需要克隆一份state

1. 下载

js 复制代码
yarn add react-redux
yarn add yarn add @reduxjs/toolkit

2. 目录结构

3. 文件编写内容

Index.js

js 复制代码
import { configureStore } from '@reduxjs/toolkit'

// 中间件
// import reduxLogger from 'redux-logger'
import reduxThunk from 'redux-thunk'

// 切片模块
import taskReducer from '../store/features/taskSlice'
// 切片原理
const store = configureStore({
  // 指定 reducer
  reducer: {
    // 按模块管理各个切片导出的reducer
    task: taskReducer,
  },
  // 使用中间件[如果我们不指定任何中间件,则默认集成了ReduxThunk,但是一旦设置,会整体替换默认值,需要手动指定thunk中间件]
  middleware: [reduxThunk],
})

export default store

切片文件=>taskReducer

js 复制代码
import { createSlice } from '@reduxjs/toolkit'

const taskSlice = createSlice({
  // 设置切片的名字
  name: 'task',
  // 设置次切片对应reducer中的初始状态
  initialState: {
    taskList: [],
    count: 0,
  },
  // 编写业务代码处
  reducers: {
    setCount(state, action) {
      // state:redux中公共状态信息.基于immer库,不需要自己克隆
      // action: 派发的行为对象,我们无需考虑行为标识,传递的其他信息,都是以action.payload的方式传递进来的值
      state.count = action.payload
    },
    setTaskList(state, action) {
      state.taskList = action.payload
    },
  },
})

// 利用promise 写一个异步的函数方法,返回一个数组
export function getTaskList() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve([1, 2, 3])
    }, 1000)
  })
}

// 从切片中获取actionCreator:此处结构的方法和上线reducers中的方法,仅仅是函数名相同;执行方法,返回需要派发的行为对象,后期我们可以基于dispatch进行任务派发即可!!
export let { setCount, setTaskList } = taskSlice.actions
console.log(setCount([])) // {"type": "task/setCount", "payload": []}

// 实现异步派发[redux-thunk]
export const getTaskListAsync = () => {
  return async (dispatch) => {
    let res = await getTaskList()
    // 注意派发时,需要使用 setTaskList
    dispatch(setTaskList(res))
  }
}

export default taskSlice.reducer

4. 入口注册store

main.js

js 复制代码
// 导入store
import store from './store'
import { Provider } from 'react-redux'
import Demo from './views/Demo'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <Demo />
    </Provider>
  </React.StrictMode>
)

5. 获取redux公共状态和派发的方法

获取公共状态 useSelector

其中 taskList, count 就是在task切片中定义的状态

js 复制代码
const { taskList, count } = useSelector((state) => state.task)

获取派发的事件 useDispatch

js 复制代码
const dispatch = useDispatch()
dispatch(setTaskList(res)) dispatch中的内容相当于 action.payload

6. extraReducers 用于处理其他切片中的action

使用场景:一个事件中,需要修改两处切片中的值,可以通过例如Aaction让A以及B进行状态的修改

例如登出功能

AutoSlice.js

这里需要删除name字段

js 复制代码
import { createSlice } from '@reduxjs/toolkit'

const logoSlice = createSlice({
  name: 'logo',
  initialState: {
    name: 'logo',
  },
  reducers: {
    delName(state, action) {
      state.name = ''
    },
  },
})

export default logoSlice.reducer
export const { delName } = logoSlice.actions

TaskSlice.js

这里需要删除userInfo字段

js 复制代码
import { delName } from './AuthSlice'
// extraReducers 用于处理其他切片中的action
  extraReducers: (builder) => {
    builder.addCase(delName, (state, action) => {
      state.userInfo = {}
 })

此时在组件中调用delName的派发事件

即可删除name 以及userInfo

js 复制代码
import { delName } from '../store/features/AuthSlice' 
const handleLogoOut = () => {
    dispatch(delName())
 }

7. 完整demo案例

  1. store/index
js 复制代码
import { configureStore } from '@reduxjs/toolkit'

// 中间
// import reduxLogger from 'redux-logger'
import reduxThunk from 'redux-thunk'

// 切片模块
import taskReducer from '../store/features/taskSlice'
import logoReducer from '../store/features/AuthSlice'
// 切片原理
const store = configureStore({
  // 指定 reducer
  reducer: {
    // 按模块管理各个切片导出的reducer
    task: taskReducer,
    logo: logoReducer,
  },
  // 使用中间件[如果我们不指定任何中间件,则默认集成了ReduxThunk,但是一旦设置,会整体替换默认值,需要手动指定thunk中间件]
  middleware: [reduxThunk],
})

export default store
  1. features/AuthSlice
js 复制代码
import { createSlice } from '@reduxjs/toolkit'

const logoSlice = createSlice({
  name: 'logo',
  initialState: {
    name: 'logo',
  },
  reducers: {
    delName(state, action) {
      state.name = ''
    },
  },
})

export default logoSlice.reducer
export const { delName } = logoSlice.actions
  1. taskSlice
js 复制代码
import { createSlice } from '@reduxjs/toolkit'
import { delName } from './AuthSlice'

const taskSlice = createSlice({
  // 设置切片的名字
  name: 'task',
  // 设置次切片对应reducer中的初始状态
  initialState: {
    taskList: [],
    count: 0,
    userInfo: {
      name: 'zs',
      age: 20,
    },
  },
  // 编写业务
  reducers: {
    setCount(state, action) {
      console.log(action)
      // state:redux中公共状态信息.基于immer库,不需要自己克隆
      // action: 派发的行为对象,我们无需考虑行为标识,传递的其他信息,都是以action.payload的方式传递进来的值
      state.count = action.payload
    },
    setTaskList(state, action) {
      state.taskList = action.payload
    },
    setUserInfo(state, action) {
      state.userInfo = action.payload
    },
  },
  // extraReducers 用于处理其他切片中的action
  extraReducers: (builder) => {
    builder.addCase(delName, (state, action) => {
      state.userInfo = {}
    })
  },
})

// 利用promise 写一个异步的函数方法,返回一个数组
export function getTaskList() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve([1, 2, 3])
    }, 1000)
  })
}

// 从切片中获取actionCreator:此处结构的方法和上线reducers中的方法,仅仅是函数名相同;执行方法,返回需要派发的行为对象,后期我们可以基于dispatch进行任务派发即可!!
export let { setCount, setTaskList } = taskSlice.actions
console.log(setCount([])) // {"type": "task/setCount", "payload": []}

// 实现异步派发[redux-thunk]
export const getTaskListAsync = () => {
  return async (dispatch) => {
    let res = await getTaskList()
    // 注意派发时,需要使用 setTaskList
    dispatch(setTaskList(res))
  }
}

export default taskSlice.reducer
  1. 项目入口
js 复制代码
// 导入store
import store from './store'
import { Provider } from 'react-redux'
import Demo from './views/Demo'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <Demo />
    </Provider>
  </React.StrictMode>
)
  1. 在某个组件中使用
js 复制代码
import { useDispatch, useSelector } from 'react-redux'
import {
  setCount,
  getTaskListAsync,
  getTaskList,
  setTaskList,
} from '../store/features/taskSlice'
import { useEffect } from 'react'
import { delName } from '../store/features/AuthSlice'

const Demo = () => {
  /* 获取redux公共状态和派发的方法 */
  const { taskList, count, userInfo } = useSelector((state) => state.task)
  const { name } = useSelector((state) => state.logo)
  const dispatch = useDispatch()

  const getData = async () => {
    const res = await getTaskList()
    dispatch(setTaskList(res))
  }
  useEffect(() => {
    // dispatch(getTaskListAsync())
    getData()
  }, [])

  const handleClick = () => {
    dispatch(setCount(count + 1))
  }
  const handleLogoOut = () => {
    dispatch(delName())
  }
  return (
    <div>
      123 - {count} - {JSON.stringify(taskList)} - {JSON.stringify(userInfo)} -{' '}
      {name}
      <br />
      <button onClick={handleClick}>add</button>
      <br />
      <button onClick={handleLogoOut}>logoOut</button>
    </div>
  )
}

export default Demo
相关推荐
鬼手点金2 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
蛋蛋的就会顺顺的3 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday3 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
朱涛的自习室3 小时前
70 美金的 Beyond Compare,我让 Gemini 4 和 DeepSeek 造个开源免费版(Day 2)
android·前端·人工智能
码艺-Alimjan4 小时前
Tauri 源码备份 · 打包 & 解压 总结,源码收集之路
前端·javascript·vue.js
小马不起床4 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
子非鱼a5 小时前
【文件上传】一个普普通通的edu16
前端
美狐美颜SDK开放平台6 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
pride.li6 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
屏什么录7 小时前
电脑如何录屏幕视频和声音?从工具到代码,7 种方案帮你彻底搞定
前端·音视频开发