安装
toolkit是redux的一个工具集,它提供了一些常用的工具函数,可以帮助我们更方便的使用redux。
npm i react-redux
npm install @reduxjs/toolkit
// 开发者工具
npm install redux-devtools
基本使用
示例文件目录结构:src->redux, redux下有actions 和 feature 连个文件夹 和一个store.js
├── src
│ ├── hooks
│ │ ├── useReduxHook.ts(ts项目中使用)
│ ├── redux
│ │ ├── feature
│ │ ├── store.js
│ ├── App.js
│ ├── index.js
文件内容
src/redux/store.js
// 创建仓库
import { configureStore } from '@reduxjs/toolkit'
// 导入reducer
import counterReducer from './feature/counterSlice'
// 创建仓库
export default configureStore({
reducer: {
counter: counterReducer
}
})
// 封装useDispatch和useSelector (只在ts中使用)
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
src/hooks/useReduxHook.ts
假如你使用的是ts,可以封装一个自定义hook,方便使用
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from "@/redux/store";
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import store from './redux/store'
import {Provider} from 'react-redux'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
// 将store传入
<Provider store={store}>
<App />
</Provider>
)
src/redux/feature/counterSlice.js
// 引入createSlice createAsyncThunk
import {createSlice, createAsyncThunk} from '@reduxjs/toolkit'
// 异步action 可用于网络请求 第一个参数为action的名字, 第二个参数为一个异步函数, 可传入参数
export const incrementAsync = createAsyncThunk(
'counter/fetchCount',
async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
return await response.json();
}
)
// 1. 创建初始状态
const initialState = {
value: 0,
}
// 2. 创建reducer
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
// 3. 创建action
increment: (state, action) => {
state.value += 1;
}
},
// 异步action 此处有两种写法
extraReducers: {
// 成功
[incrementAsync.fulfilled]: (state, action) => {
state.value += 1;
},
// 请求中
[incrementAsync.pending]: (state, action) => {
console.log('pending');
},
// 失败
[incrementAsync.rejected]: (state, action) => {
console.log('rejected');
}
}
})
// 4. 导出action
export const {increment} = counterSlice.actions;
// 5. 导出reducer
export default counterSlice.reducer;
使用
src/App.js
import React from 'react'
// 引入dispatch
import { useDispatch } from 'react-redux'
// 引入useSelector
import { useSelector } from 'react-redux'
// 假如你使用的是ts, 且封装了自定义hook
// import { useAppDispatch, useAppSelector } from '@/hooks/useReduxHook'
// 引入action
import { increment, incrementAsync } from './redux/feature/counterSlice'
export default function App(props) {
// 获取dispatch
const dispatch = useDispatch()
// 获取状态
const countValue = useSelector(state => state.counter.value)
// 处理异步action
const handleClick = async () => {
// 等待异步action完成
await dispatch(incrementAsync())
console.log('done');
}
return (
<div>
{countValue}
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={handleClick}>+ async</button>
</div>
)
}
持久化
安装
npm install redux-persist
使用
src/redux/store.js
// 创建仓库
import { configureStore } from '@reduxjs/toolkit'
import storageSession from 'redux-persist/lib/storage/session';
// 可换成storageSession
// import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
import thunk from "redux-thunk";
// 导入reducer
import counterReducer from './feature/counterSlice'
// 配置
const persistConfig = {
key: 'userStore',
storage: storageSession,
}
// 持久化reducer
const persistedReducer = persistReducer(persistConfig, counterReducer)
// 创建仓库
export default configureStore({
reducer: {
// 传入持久化reducer
counter: persistedReducer
},
middleware: [thunk],
})
// 导出持久化store
export const persistor = persistStore(store)
src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import store from './redux/store'
import { PersistGate } from 'redux-persist/integration/react';
import { persistor } from "@/redux/store";
import { Provider } from 'react-redux'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
// 将store传入
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
)