【Taro】使用 Redux Toolkit 要比传统的 Redux action写法更好一些吗?Redux Toolkit有什么作用,可以更好的 提升性能吗?

134 阅读4分钟

使用 Redux Toolkit 通常比传统的 Redux 写法更好一些,主要原因如下:

1. 简化 Redux 配置

Redux Toolkit 提供了许多内置的方法和工具,简化了 Redux 的配置,减少了样板代码。你不再需要手动定义 action types、action creators 和 reducers,可以使用 createSlice 一次性生成这些部分。

2. 内置的不可变状态管理

Redux Toolkit 使用 immer 库来处理状态的不可变性,因此你可以使用更加直观的“可变”代码来更新状态,Redux Toolkit 会在幕后自动处理状态的不可变性。

3. 包含常见的开发工具

Redux Toolkit 默认集成了 Redux DevTools 和 Redux Thunk 中间件,提供了更好的开发体验。你可以轻松地在项目中使用这些工具,而不需要额外的配置。

4. 减少样板代码

通过使用 createSlicecreateAsyncThunk 等方法,Redux Toolkit 大大减少了 Redux 中的样板代码,使代码更加简洁易读。

5. 更好的类型支持

Redux Toolkit 提供了更好的 TypeScript 支持,使得在 TypeScript 项目中使用 Redux 变得更加方便和安全。

6. 更好的性能

虽然 Redux Toolkit 本身并没有特别提升性能的功能,但它鼓励最佳实践,如使用不可变状态更新和减少样板代码,这些都有助于维护代码的性能和可靠性。

Redux Toolkit 的作用

  1. 简化 Redux 配置:提供 configureStorecreateSlice 等 API,简化 store 的创建和 reducer 的定义。
  2. 内置不可变管理:使用 immer 库处理状态的不可变性,简化状态更新。
  3. 集成开发工具:默认集成了 Redux DevTools 和 Redux Thunk 中间件,提供更好的开发体验。
  4. 减少样板代码:通过 createSlicecreateAsyncThunk 等方法,减少 Redux 中的样板代码。
  5. 更好的类型支持:提供更好的 TypeScript 支持,使 TypeScript 项目中的 Redux 使用更加方便和安全。

性能提升

虽然 Redux Toolkit 本身并没有特别的性能提升功能,但它通过以下方式间接提升了性能和开发体验:

  1. 鼓励不可变状态更新:使用 immer 库处理状态的不可变性,确保状态更新的正确性,减少错误。
  2. 减少样板代码:简化 Redux 配置和状态管理,使代码更加简洁易读,减少了出错的可能性。
  3. 集成开发工具:提供更好的开发工具,如 Redux DevTools 和 Redux Thunk,方便调试和开发。

示例:使用 Redux Toolkit 简化代码

以下是使用 Redux Toolkit 重构后的代码示例,展示了如何简化 Redux 配置和状态管理。

定义 Slice

在 src/store/slices/recommendUsersSlice.ts 中定义 slice:

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface User {
  id: number;
  name: string;
  recommendation: string;
}

interface RecommendUsersState {
  users: User[];
}

const initialState: RecommendUsersState = {
  users: [],
};

const recommendUsersSlice = createSlice({
  name: 'recommendUsers',
  initialState,
  reducers: {
    getRecommendUsers: (state) => {
      // No additional state changes needed here
    },
    setRecommendUsers: (state, action: PayloadAction<User[]>) => {
      state.users = action.payload;
    },
  },
});

export const { getRecommendUsers, setRecommendUsers } = recommendUsersSlice.actions;

export default recommendUsersSlice.reducer;

定义 Sagas

在 src/store/sagas/recommendUsersSaga.ts 中定义 recommendUsers 的 Saga:

import { call, put, takeLatest } from 'redux-saga/effects';
import { getRecommendUsers, setRecommendUsers } from '../slices/recommendUsersSlice';
import { getRecommendUsersApi } from '../api';

function* fetchRecommendUsers() {
  try {
    const response = yield call(getRecommendUsersApi);
    yield put(setRecommendUsers(response.data));
  } catch (error) {
    console.error('Failed to fetch recommend users', error);
  }
}

export function* watchGetRecommendUsers() {
  yield takeLatest(getRecommendUsers.type, fetchRecommendUsers);
}

组合所有 Sagas

在 src/store/sagas/index.ts 中组合所有 Sagas:

import { all } from 'redux-saga/effects';
import { watchGetRecommendUsers } from './recommendUsersSaga';

export default function* rootSaga() {
  yield all([watchGetRecommendUsers()]);
}

定义 API 请求

在 src/store/api/index.ts 中定义 API 请求:

import axios from 'axios';

const API_BASE_URL = '/api';

export const getRecommendUsersApi = () => {
  return axios.get(`${API_BASE_URL}/recommend-users`);
};

创建 Redux Store

在 src/store/index.ts 中创建 Redux Store:

import { configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import recommendUsersReducer from './slices/recommendUsersSlice';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = configureStore({
  reducer: {
    recommendUsers: recommendUsersReducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(sagaMiddleware),
});

sagaMiddleware.run(rootSaga);

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

export default store;

使用 Redux 和 Sagas 在组件中获取数据

在你的组件中使用 useSelector 和 useDispatch 进行数据获取和操作:

// src/pages/home/index.tsx
import React, { useEffect } from "react";
import { View, Text, Image } from "@tarojs/components";
import { useDispatch, useSelector } from "react-redux";
import "./index.less";
import { getRecommendUsers } from "@/store/slices/recommendUsersSlice";
import { RootState } from "@/store";

const HomePage: React.FC = () => {
  const dispatch = useDispatch();
  const recommendUsers = useSelector((state: RootState) => state.recommendUsers.users);
  console.log("recommendUsers", recommendUsers);

  useEffect(() => {
    dispatch(getRecommendUsers());
  }, [dispatch]);

  return (
    <View className="home">
      {recommendUsers?.map((user) => (
        <View key={user.id} className="user-card">
          <Image className="avatar" src={user.avatar} />
          <View className="user-info">
            <Text className="username">{user.name}</Text>
            <Text className="recommendation">{user.recommendation}</Text>
          </View>
        </View>
      ))}
    </View>
  );
};

export default HomePage;

确保 Provider 正确配置

确保你的应用程序被 Redux 的 Provider 包裹,并且正确地传递了 store:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

总结

通过使用 Redux Toolkit,你可以简化 Redux 的配置和状态管理,减少样板代码,并提供更好的开发体验。虽然 Redux Toolkit 本身并没有特别提升性能的功能,但它鼓励最佳实践,如使用不可变状态更新和减少样板代码,这些都有助于维护代码的性能和可靠性。