安装redux包
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit
新建store
创建store文件夹,在其中新建index.ts文件,作为总的store仓库管理
import { configureStore } from '@reduxjs/toolkit'
import undoable, { excludeAction, StateWithHistory } from 'redux-undo'
import countReducer from './count'
import todoListReducer, { TodoItemType } from './todoList'
export type StateType = {
count: number
todoList: StateWithHistory<TodoItemType[]>
}
export default configureStore({
reducer: {
count: countReducer,
// // 没有 undo redo
// todoList: todoListReducer
// 加了 undo
todoList: undoable(todoListReducer, {
limit: 20, // 限制只能撤销 20 步
filter: excludeAction(['todoList/toggleCompleted']) // 屏蔽某些 action ,不进行 undo redo
})
// 扩展其他模块
}
})
其中countReducer是为管理加减信息的,从count.ts文件中导入(后文提及)
创建每一个状态的reducer(这里以count加减法为例):
注意需导出actions方法和整个reducer函数
import { createSlice } from '@reduxjs/toolkit'
const INIT_STATE: number = 100
export const countSlice = createSlice({
name: 'count', // 模块的名字(redux store 默认可以拆分模块的)
initialState: INIT_STATE,
reducers: {
increase(state: number) {
return state + 1
},
decrease(state: number) {
return state - 1 // 返回一个新的 state ,不可变数据
}
}
})
export const { increase, decrease } = countSlice.actions
export default countSlice.reducer
组件中运用
import React, { FC } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { increase, decrease } from '../store/count'
import type { StateType } from '../store/index'
const Count: FC = () => {
const count = useSelector<StateType>(state => state.count)
const dispatch = useDispatch()
return <div>
<span><>count: {count}</></span>
<button onClick={() => dispatch(increase())}>+</button>
<button onClick={() => dispatch(decrease())}>-</button>
</div>
}
export default Count
根组件处理
需要在根组件中用<Provider>包裹,并且传入仓库store
import React from 'react';
import ReactDOM from 'react-dom/client';
// import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux'
import store from './store/index'
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<Provider store={store}>
<App />
</Provider>
);
以防忘记,文件列表如下