使用 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. 减少样板代码
通过使用 createSlice
、createAsyncThunk
等方法,Redux Toolkit 大大减少了 Redux 中的样板代码,使代码更加简洁易读。
5. 更好的类型支持
Redux Toolkit 提供了更好的 TypeScript 支持,使得在 TypeScript 项目中使用 Redux 变得更加方便和安全。
6. 更好的性能
虽然 Redux Toolkit 本身并没有特别提升性能的功能,但它鼓励最佳实践,如使用不可变状态更新和减少样板代码,这些都有助于维护代码的性能和可靠性。
Redux Toolkit 的作用
- 简化 Redux 配置:提供
configureStore
、createSlice
等 API,简化 store 的创建和 reducer 的定义。 - 内置不可变管理:使用
immer
库处理状态的不可变性,简化状态更新。 - 集成开发工具:默认集成了 Redux DevTools 和 Redux Thunk 中间件,提供更好的开发体验。
- 减少样板代码:通过
createSlice
、createAsyncThunk
等方法,减少 Redux 中的样板代码。 - 更好的类型支持:提供更好的 TypeScript 支持,使 TypeScript 项目中的 Redux 使用更加方便和安全。
性能提升
虽然 Redux Toolkit 本身并没有特别的性能提升功能,但它通过以下方式间接提升了性能和开发体验:
- 鼓励不可变状态更新:使用
immer
库处理状态的不可变性,确保状态更新的正确性,减少错误。 - 减少样板代码:简化 Redux 配置和状态管理,使代码更加简洁易读,减少了出错的可能性。
- 集成开发工具:提供更好的开发工具,如 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 本身并没有特别提升性能的功能,但它鼓励最佳实践,如使用不可变状态更新和减少样板代码,这些都有助于维护代码的性能和可靠性。