学习 Redux 工具包 - React (TypeScript)

什么是 Redux 和 Redux Toolkit

**Redux** 是一个状态管理库,可帮助管理 React 应用程序中的状态。**Redux Toolkit** 是一个官方库,用于以比常规 Redux 更简单、更结构化的方式管理 React 应用程序中的全局状态。

Redux 关键概念

  • 存储:存储应用程序状态的地方。
  • 动作:描述您想要执行的操作的对象。通常具有类型和有效负载。
  • Reducer:根据收到的动作确定如何改变状态的函数。
  • Dispatch:将动作发送到商店的方法。
  • 选择器:从存储中检索数据的函数。
  • Redux Toolkit(RTK)简化

    RTK 通过以下功能简化了 Redux 的设置:

  • configureStore():使用默认设置创建一个商店。
  • createSlice():将动作和reducer合并到一个地方。
  • createAsyncThunk():像 API 调用一样管理异步数据。
  • 设置项目

    使用 vite 安装 react

    npm create vite@latest

    安装 react redux 和 redux 工具包

    npm install @reduxjs/toolkit react-redux

    项目结构

    Project Structure

    基本步骤

    设置商店

    // store.ts
    
    import { configureStore } from '@reduxjs/toolkit';
    
    export const store = configureStore({
      reducer: {},
    });
    
    export type RootState = ReturnType;
    export type AppDispatch = typeof store.dispatch;

    与应用程序集成

    // main.tsx
    
    import { StrictMode } from 'react';
    import { createRoot } from 'react-dom/client';
    import { Provider } from 'react-redux';
    import App from './App.tsx';
    import './index.css';
    import { store } from './state/store.ts';
    
    const root = createRoot(document.getElementById('root')!);
    
    root.render(
      
        
          
        
      
    );

    创建切片

    // counterSlice.ts
    import { createSlice, PayloadAction } from '@reduxjs/toolkit';
    
    interface CounterState {
      value: number;
    }
    
    const initialState: CounterState = {
      value: 0,
    };
    
    const counterSlice = createSlice({
      name: 'counter',
      initialState,
      reducers: {
        increment: (state) => {
          state.value += 1;
        },
        decrement: (state) => {
          state.value -= 1;
        },
        incrementByAmount: (state, action: PayloadAction) => {
          state.value += action.payload;
        },
      },
    });
    
    export const { increment, decrement, incrementByAmount } = counterSlice.actions;
    export default counterSlice.reducer;

    更新 store.ts

    import { configureStore } from '@reduxjs/toolkit';
    import counterReducer from './slice/counterSlice';
    
    export const store = configureStore({
      reducer: {
        counter: counterReducer,
      },
    });
    
    export type RootState = ReturnType;
    export type AppDispatch = typeof store.dispatch;

    在组件中使用 redux

    // App.tsx
    
    import { useDispatch, useSelector } from 'react-redux';
    import { AppDispatch, RootState } from './state/store';
    import {
      decrement,
      increment,
      incrementByAmount,
    } from './state/slice/counterSlice';
    
    export default function App() {
      const count = useSelector((state: RootState) => state.counter.value);
      const dispatch: AppDispatch = useDispatch();
    
      return (
        
    {count}
    ); }

    实现 Redux Persist

    Redux 中的 **Persist** 用于将应用程序状态保存到本地存储(localStorage 或 sessionStorage),以便在用户刷新页面时数据不会丢失。Redux Toolkit 在 `redux-persist` 库的帮助下支持此功能。

    安装 redux persist

    npm install redux-persist

    更新 store.ts

    import { configureStore } from '@reduxjs/toolkit';
    import counterReducer from './slice/counterSlice';
    import storage from 'redux-persist/lib/storage';
    import { persistReducer, persistStore } from 'redux-persist';
    
    const persistConfig = {
      key: 'root',
      storage,
    };
    
    const persistedReducer = persistReducer(persistConfig, counterReducer);
    
    export const store = configureStore({
      reducer: {
        counter: persistedReducer,
      },
    });
    
    export const persistor = persistStore(store);
    export type RootState = ReturnType;
    export type AppDispatch = typeof store.dispatch;

    更新 main.tsx

    import { StrictMode } from 'react';
    import { createRoot } from 'react-dom/client';
    import './index.css';
    import App from './App.tsx';
    import { Provider } from 'react-redux';
    import { persistor, store } from './state/store.ts';
    import { PersistGate } from 'redux-persist/integration/react';
    
    const root = createRoot(document.getElementById('root')!);
    
    root.render(
      
        
          
            
          
        
      
    );