React redux-toolkit 的基本用法

最近在研究 redux 的一些用法,目前在 react中使用 redux 的话,基本分为两种用法:

  • 使用 redux,这个是非官方团队在维护的,而且不单在 react项目中可以使用,在 vue 的项目中也可以使用
  • 使用 react-redux,这个是 Facebook 官方在维护,不过其中的一些 API 相对来说有点难理解

React 官方团队目前针对 react 项目中的状态管理,比较推荐的做法是使用 @reduxjs/toolkit + react-redux 这种方式,这种方式简化了之前的一些操作,特别是 action type 上,当然相对地,也需要了解一下 toolkit 中的一些概念和 API,弄清楚后就会发现,使用 toolkit 来操作 redux 会方便很多

安装

$ npm install @reduxjs/toolkit react-redux
or
$ yarn add @reduxjs/toolkit react-redux

这里有两个需要注意的地方:

  • 安装 toolkit 的时候,注意是 @reduxjs,通常我们习惯了叫 redux,所以如果不是 copy 的话,容易误写成 react 或者 redux
  • 安装 @reduxjs/toolkit 的时候,同时也需要安装 react-redux,当然了,可以选择一行命令安装完,也可以选择分别安装

创建 store

// store.js
// toolkit 包里面,暴露了一个 configureStore 的方法来创建 store
import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
    reducer: {
        counter: counterReducer
    }
})

toolkit 中会暴露一个 configureStore 的方法,见名知意,这个方法是用来配置 store 的,这个方法接收一个对象作为参数,其中这个对象应该有一个必要的属性 reducer,(reducer应为一个对象),四个可选的属性:middleware, devTools,preloadedState,enhancers,这里主要讨论 reducer 的用法,至于其他的几个可选属性这里就不讲了

使用 toolkit,其中有一个比较核心的方法就是 createSlice,这个方法是创建一个 store 切片,可以理解为 vuex 中的模块,这个 slice 中包含完整的 state,用于修改 state 的 reducer 方法

创建一个 store slice

// 引入 createSlice 方法
import { createSlice } from '@reduxjs/toolkit'

// 初始化 state,这个位置不一定放在这里
const initState = 0

// createSlice 接收一个对象作为参数
export const counterSlice = createSlice({
    name: 'counter', // slice 的名字,类似一种命名空间,需要注意重名的问题
    initialState: initState, // 初始 state: any 类型
    reducers: { // 一个包含 reducer function 的对象
        increment: state => { // 这里的参数 state 就是指的 initialState
            state += 1
        }
    }, 
})
// action type 处理方式为 name/reducers function name, 比如示例中slice 的aciton type 
// 最终会解析成 counter/increment

export const { increment } = counterSlice.actions
export default counterSlice.reducer

上面这个例子中,初看之下,比较难理解的是 export default counterSlice.reducer 中的 .reducer 了,实际上 createSlice 是对传入的参数进行了处理的,它处理过后的返回值如下(来源于官方文档):

//createSlice 是有返回值的,返回值如下
{
    name : string, // 与参数中的 name 一样
    reducer : ReducerFunction, // 这个值就是用来放在 configureStore 的 reducer 中的
    actions : Record<string, ActionCreator>, // 参数中的 reducers
    caseReducers: Record<string, CaseReducer>,
    getInitialState: () => State // 返回初始的 state
}

挂载 store

// index.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import store from './store' // 引入 store
import App from './App' // App.jsx

// 使用 store 需要用到 react-redux,所以前面才说需要同时安装 toolkit 和 react-redudx
import { Provider } from 'react-redux'

ReactDOM.render(
   <Provider store={store}>
      <App />
   </Provider>
)

组件中使用 store

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { increment } from 'counterSlice'

export function Counter() {
    const dispatch = useDispatch()
    // useSelector()方法用于读取store中的data
    const value = useSelect((state) => state.counter)
    
    return (
        <>
        	<button onClick={() => dispatch(increment())}>Increment</button>
        </>
    )
}

版权声明:本文为qq_24185803原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。