Redux Toolkit

本文介绍了如何在React应用中使用ReduxToolkit(RTK)简化状态管理,包括如何使用configureStore替代手动合并reducer,以及如何通过createSlice自动创建reducer和action。详细展示了如何在实际项目中集成和使用RTK的各个组件。
摘要由CSDN通过智能技术生成

看这篇文章之前,请先阅读《Redux的介绍以及使用(内附完整代码)》这篇文章的内容!!

简介

Redux还为我们提供了一种使用Redux的方式——Redux Toolkit,Redux工具包,简称RTK。RTK可以帮助我们处理使用Redux过程中的重复性工作,简化Redux中的各种操作。

安装

无论是RTK还是Redux,在React中使用时react-redux都是必不可少,所以使用RTK依然需要安装两个包:react-redux和@reduxjs/toolkit。

npm install react-redux @reduxjs/toolkit -S

configureStore

使用RTK时,reducer依然可以使用之前的创建方式不变,但是不在需要合并reducer。RTK为我们提供了一个configureStore方法,它直接接收一个对象作为参数,可以将reducer的相关配置直接通过该对象传递,而不再需要单独合并reducer。

之前redux那一小节是使用的是combineReducers和createStore

const reducers = combineReducers({
  pageAReducer,
  pageBReducer
})

const store = configureStore(reducers)

修改为

const reducers = {
  reducer: {
    pageAReducer,
    pageBReducer
  }
}

const store = configureStore(reducers)

configureStore需要一个对象作为参数,在这个对象中可以通过不同的属性来对store进行设置,比如:reducer属性用来设置store中关联到的reducer,preloadedState用来指定state的初始值等。

reducer属性可以直接传递一个reducer,也可以传递一个对象作为值。如果只传递一个reducer,则意味着store中只有一个reducer。若传递一个对象作为参数,对象的每个属性都可以执行一个reducer,在方法内部它会自动对这些reducer进行合并。

CreateSlice

createSlice是一个全自动的创建reducer切片的方法,在它的内部调用就是createAction和createReducer,之所以先介绍那两个也是这个原因。createSlice需要一个对象作为参数,对象中通过不同的属性来指定reducer的配置信息。

createSlice(configuration object)

配置对象中的属性:

initialState —— state的初始值

name —— reducer的名字,会作为action中type属性的前缀,不要重复

reducers —— reducer的具体方法,需要一个对象作为参数,可以以方法的形式添加reducer,RTK会自动生成action对象。

例如创建pageASlice

const pageASlice = createSlice({
  name: 'pageAReducer',
  initialState: {
    num: 20
  },
  reducers: {
    setAddNum(state, action) {
      state.num = state.num + action.payload
    },
    setSubNum(state, action) {
      state.num = state.num - action.payload
    }
  }
})

createSlice返回的并不是一个reducer对象而是一个slice对象(切片对象)。这个对象中我们需要使用的属性现在有两个一个叫做actions,一个叫做reducer。

Actions

切片对象会根据我们对象中的reducers方法来自动创建action对象,这些action对象会存储到切片对象actions属性中:

console.log(pageASlice.actions);

打印结果

actions中的方法,可以通过解构赋值获取到切片中的action。开发中可以将这些取出的action对象作为组件向外部导出,导出其他组件就可以直接导入这些action,然后即可通过action来触发reducer。

export const { setAddNum, setSubNum } = pageASlice.actions

Reducer

切片的reducer属性是切片根据我们传递的方法自动创建生成的reducer,需要将其作为reducer传递进configureStore的配置对象中以使其生效:

export const { reducer: pageAReducer } = pageASlice


const store = configureStore({
  reducer: {
    pageAReducer
  }
})

完整代码示例

我们现在利用RTK来改造《Redux的介绍以及使用(内附完整代码)》这节的内容

目录结构

components

src\components\PageA.jsx

import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { setAddNum, setSubNum } from '../store/slice/PageA/pageASlice'

export default function () {
  const pagea = useSelector(state => {
    return state.pageAReducer
  })
  const dispatch = useDispatch()

  const onClickOne = () => {
    dispatch(setAddNum(1))
  }

  const onClickTwo = () => {
    dispatch(setSubNum(2))
  }
  return (
    <div>
      <button onClick={onClickOne}>增加</button>
      <p>{pagea.num}</p>
      <button onClick={onClickTwo}>减少</button>
    </div>
  )
}

src\components\PageB.jsx

import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { setPushNum } from '../store/slice/PageB/pageBSlice'

export default function PageB() {
  const dispatch = useDispatch();
  const pageb = useSelector(state => state.pageBReducer)

  const onClick = () => {
    dispatch(setPushNum(50))
  }

  return (
    <div>
      <button onClick={onClick}>变化</button>
      <p>{pageb.arr.join(" ")}</p>
    </div>
  )
}

slice

src\store\slice\PageA\pageASlice.jsx

import { createSlice } from "@reduxjs/toolkit"

const pageASlice = createSlice({
  name: 'pageAReducer',
  initialState: {
    num: 20
  },
  reducers: {
    setAddNum(state, action) {
      state.num = state.num + action.payload
    },
    setSubNum(state, action) {
      state.num = state.num - action.payload
    }
  }
})

export const { setAddNum, setSubNum } = pageASlice.actions

export const { reducer: pageAReducer } = pageASlice

src\store\slice\PageB\pageBSlice.jsx

import { createSlice } from "@reduxjs/toolkit";

const pageBSlice = createSlice({
  name: 'pageBReducer',
  initialState: {
    arr: [10, 20, 30]
  },
  reducers: {
    setPushNum(state, action) {
      state.arr.push(action.payload)
    }
  }
})

export const { setPushNum } = pageBSlice.actions

export const { reducer: pageBReducer } = pageBSlice

store

src\store\index.jsx

import { configureStore } from "@reduxjs/toolkit";
import { pageAReducer } from './slice/PageA/pageASlice'
import { pageBReducer } from './slice/PageB/pageBSlice'

const store = configureStore({
  reducer: {
    pageAReducer,
    pageBReducer
  }
})

export default store
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值