安装

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>
)
Last Updated:
Contributors: 黄定鑫