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
相关推荐
Jiaberrr3 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy3 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白3 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、3 小时前
Web Worker 简单使用
前端
web_learning_3213 小时前
信息收集常用指令
前端·搜索引擎
tabzzz3 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百3 小时前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao4 小时前
自动化测试常用函数
前端·css·html5
码爸4 小时前
flink doris批量sink
java·前端·flink
深情废杨杨4 小时前
前端vue-父传子
前端·javascript·vue.js