最近在研究 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版权协议,转载请附上原文出处链接和本声明。