Redux 完全教程

第一章:Redux 基础概念

1.1 Redux 是什么?

Redux 是一个可预测的状态容器,用于 JavaScript 应用的状态管理。

练习 1.1:基本 Redux 配置

创建一个简单的 Redux store。

store/index.js
import { createStore } from 'redux' // 初始状态 const initialState = { count: 0 } // reducer function counterReducer(state = initialState, action) { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + 1 } case 'DECREMENT': return { ...state, count: state.count - 1 } default: return state } } // 创建 store const store = createStore(counterReducer) export default store
App.jsx
import { useSelector, useDispatch } from 'react-redux' function App() { const count = useSelector(state => state.count) const dispatch = useDispatch() return ( <div> <h2>Count: {count}</h2> <button onClick={() => dispatch({ type: 'INCREMENT' })}>增加</button> <button onClick={() => dispatch({ type: 'DECREMENT' })}>减少</button> </div> ) }

第二章:React-Redux

2.1 Provider 和 Connect

使用 Provider 和 Connect 连接 React 和 Redux。

练习 2.1:Provider 配置

配置 React-Redux Provider。

index.js
import React from 'react' import { createRoot } from 'react-dom/client' import { Provider } from 'react-redux' import store from './store' import App from './App' const root = createRoot(document.getElementById('root')) root.render( <Provider store={store}> <App /> </Provider> )

2.2 Hooks API

使用 React-Redux Hooks。

练习 2.2:Hooks 示例

展示 useSelector 和 useDispatch 的使用。

Counter.jsx
import { useSelector, useDispatch } from 'react-redux' function Counter() { const count = useSelector(state => state.count) const dispatch = useDispatch() return ( <div> <h2>Count: {count}</h2> <button onClick={() => dispatch({ type: 'INCREMENT' })}>增加</button> <button onClick={() => dispatch({ type: 'DECREMENT' })}>减少</button> </div> ) }

第三章:Redux Toolkit

3.1 createSlice

使用 createSlice 简化 Redux 代码。

练习 3.1:createSlice 示例

展示 createSlice 的使用。

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

3.2 configureStore

使用 configureStore 配置 Redux store。

练习 3.2:configureStore 示例

展示 configureStore 的使用。

store/index.js
import { configureStore } from '@reduxjs/toolkit' import counterReducer from './counterSlice' export const store = configureStore({ reducer: { counter: counterReducer } })

3.3 createAsyncThunk

使用 createAsyncThunk 处理异步操作。

练习 3.3:异步操作示例

展示 createAsyncThunk 的使用。

store/userSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' import axios from 'axios' // 创建异步 thunk export const fetchUser = createAsyncThunk( 'user/fetchUser', async (userId) => { const response = await axios.get(`/api/users/${userId}`) return response.data } ) const userSlice = createSlice({ name: 'user', initialState: { data: null, status: 'idle', error: null }, reducers: {}, extraReducers: (builder) => { builder .addCase(fetchUser.pending, (state) => { state.status = 'loading' }) .addCase(fetchUser.fulfilled, (state, action) => { state.status = 'succeeded' state.data = action.payload }) .addCase(fetchUser.rejected, (state, action) => { state.status = 'failed' state.error = action.error.message }) } }) export default userSlice.reducer

第四章:最佳实践

4.1 项目结构

Redux 项目的最佳结构。

项目结构示例
src/ ├── store/ │ ├── index.js │ ├── counterSlice.js │ └── userSlice.js ├── components/ │ ├── Counter.jsx │ └── UserProfile.jsx └── App.jsx

4.2 性能优化

Redux 性能优化技巧。

性能优化示例
// 1. 使用 reselect 创建记忆化的选择器 import { createSelector } from '@reduxjs/toolkit' const selectUser = state => state.user export const selectUserData = createSelector( [selectUser], user => user.data ) // 2. 使用 shallowEqual 优化 useSelector import { shallowEqual } from 'react-redux' function UserProfile() { const user = useSelector(selectUserData, shallowEqual) // ... } // 3. 使用 createEntityAdapter 管理规范化数据 import { createEntityAdapter } from '@reduxjs/toolkit' const usersAdapter = createEntityAdapter() const usersSlice = createSlice({ name: 'users', initialState: usersAdapter.getInitialState(), reducers: { addUser: usersAdapter.addOne, updateUser: usersAdapter.updateOne, removeUser: usersAdapter.removeOne } })

第五章:常见问题解答

5.1 常见错误

列举并解决使用 Redux 时常见的错误。

常见错误及解决方案
// 错误1:直接修改状态 // ❌ 错误做法 state.count += 1 // ✅ 正确做法 return { ...state, count: state.count + 1 } // 错误2:忘记添加 Provider // ❌ 错误做法 <App /> // ✅ 正确做法 <Provider store={store}> <App /> </Provider> // 错误3:在 reducer 中执行异步操作 // ❌ 错误做法 reducer(state, action) { fetch('/api/data').then(...) } // ✅ 正确做法 // 使用 createAsyncThunk 或中间件处理异步操作

5.2 调试技巧

介绍 Redux 的调试工具和技巧。

调试技巧示例
// 1. 使用 Redux DevTools // 安装 Redux DevTools 浏览器扩展 // 2. 使用 logger 中间件 import { configureStore } from '@reduxjs/toolkit' import logger from 'redux-logger' const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger) }) // 3. 使用 Redux Toolkit 的调试工具 import { configureStore } from '@reduxjs/toolkit' const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production' })

学习建议

建议按照章节顺序学习,每完成一个练习后再进行下一个。遇到问题时,可以查看对应的常见问题解答部分。