Redux 技术栈使用总结
1. Redux 基本概念
Redux 是一个用于管理 JavaScript 应用状态的容器,遵循单向数据流原则。
核心概念
- Store: 存储应用状态的单一数据源
- Action: 描述状态变化的对象(必须包含
type属性) - Reducer: 纯函数,根据当前状态和 action 返回新状态
- Dispatch: 触发 action 的方法
- Subscribe: 监听状态变化的方法
基本工作流程
View -> Dispatch Action -> Reducer -> Store -> View
简单示例
// Action Types
const INCREMENT = 'INCREMENT'
const DECREMENT = 'DECREMENT'
// Action Creators
function increment() {
return { type: INCREMENT }
}
function decrement() {
return { type: DECREMENT }
}
// Reducer
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 }
case DECREMENT:
return { count: state.count - 1 }
default:
return state
}
}
// Store
import { createStore } from 'redux'
const store = createStore(counterReducer)
// 使用
store.dispatch(increment())
console.log(store.getState()) // { count: 1 }
2. React-Redux 在 React 组件中的使用
React-Redux 是 Redux 的官方 React 绑定库,提供了将 Redux 状态连接到 React 组件的方法。
核心 API
- Provider: 包裹应用,提供 Redux store
- connect: 高阶组件,将组件连接到 Redux store
使用示例
import React from 'react'
import { Provider, connect } from 'react-redux'
import { createStore } from 'redux'
import counterReducer from './reducers'
// 创建 store
const store = createStore(counterReducer)
// 展示组件
class CounterComponent extends React.Component {
render() {
const { count, increment, decrement } = this.props
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
)
}
}
// 映射 state 到 props
const mapStateToProps = (state) => {
return { count: state.count }
}
// 映射 dispatch 到 props
const mapDispatchToProps = (dispatch) => {
return {
increment: () => dispatch({ type: 'INCREMENT' }),
decrement: () => dispatch({ type: 'DECREMENT' })
}
}
// 连接组件
const Counter = connect(mapStateToProps, mapDispatchToProps)(CounterComponent)
// 应用入口
const App = () => (
<Provider store={store}>
<Counter />
</Provider>
)
3. React-Redux 在 React Hooks 中的使用
React-Redux 提供了 Hooks API,使函数组件可以更方便地使用 Redux。
核心 Hooks
- useSelector: 从 Redux store 中获取状态
- useDispatch: 获取 dispatch 函数
使用示例
import React from 'react'
import { Provider, useSelector, useDispatch } from 'react-redux'
import { createStore } from 'redux'
import counterReducer from './reducers'
// 创建 store
const store = createStore(counterReducer)
// 函数组件
const Counter = () => {
// 获取状态
const count = useSelector(state => state.count)
// 获取 dispatch
const dispatch = useDispatch()
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
</div>
)
}
// 应用入口
const App = () => (
<Provider store={store}>
<Counter />
</Provider>
)
4. Redux Thunk 的使用
Redux Thunk 是 Redux 的中间件,用于处理异步操作。
核心概念
- 允许 action creator 返回函数而不是普通对象
- 这个函数可以接收
dispatch和getState作为参数 - 可以在函数内部执行异步操作,完成后分发普通 action
使用示例
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import counterReducer from './reducers'
// 创建带有 thunk 中间件的 store
const store = createStore(counterReducer, applyMiddleware(thunk))
// 异步 Action Creator
const fetchUser = (userId) => {
return async (dispatch, getState) => {
// 分发请求开始的 action
dispatch({ type: 'FETCH_USER_REQUEST' })
try {
// 执行异步操作
const response = await fetch(`https://api.example.com/users/${userId}`)
const user = await response.json()
// 分发请求成功的 action
dispatch({ type: 'FETCH_USER_SUCCESS', payload: user })
} catch (error) {
// 分发请求失败的 action
dispatch({ type: 'FETCH_USER_FAILURE', payload: error.message })
}
}
}
// 使用
dispatch(fetchUser(123))
5. Redux Toolkit 的概念和使用
Redux Toolkit 是官方推荐的 Redux 开发工具集,旨在简化 Redux 开发。
核心概念和 API
- configureStore: 简化 store 创建,自动配置中间件和 devtools
- createSlice: 自动生成 reducer 和 action creators
- createAsyncThunk: 创建异步 thunk,自动处理 pending/fulfilled/rejected 状态
- Immer 集成: 允许直接修改状态对象,自动转换为不可变更新
使用示例
import { configureStore, createSlice, createAsyncThunk } from '@reduxjs/toolkit'
// 异步 thunk
const fetchUser = createAsyncThunk(
'user/fetchUser',
async (userId) => {
const response = await fetch(`https://api.example.com/users/${userId}`)
return response.json()
}
)
// 创建 slice
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
user: null,
loading: false,
error: null
},
// 同步 reducers
reducers: {
increment: (state) => {
state.value += 1 // 直接修改状态
},
decrement: (state) => {
state.value -= 1
}
},
// 异步状态处理
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.loading = true
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.loading = false
state.user = action.payload
})
.addCase(fetchUser.rejected, (state, action) => {
state.loading = false
state.error = action.payload
})
}
})
// 自动生成的 action creators
export const { increment, decrement } = counterSlice.actions
// 创建 store
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
})
// 在组件中使用
import { useSelector, useDispatch } from 'react-redux'
import { increment, decrement, fetchUser } from './counterSlice'
const Component = () => {
const { value, user, loading } = useSelector(state => state.counter)
const dispatch = useDispatch()
return (
<div>
<p>Count: {value}</p>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
<button onClick={() => dispatch(fetchUser(123))} disabled={loading}>
{loading ? 'Loading...' : 'Fetch User'}
</button>
{user && <p>User: {user.name}</p>}
</div>
)
}
总结
- Redux: 管理应用状态的容器,遵循单向数据流
- React-Redux: 将 Redux 与 React 组件连接,提供
Provider、connect等 API - React-Redux Hooks: 提供
useSelector和useDispatch,简化函数组件使用 Redux - Redux Thunk: 处理异步操作的中间件,允许 action creator 返回函数
- Redux Toolkit: 官方推荐的开发工具集,简化 Redux 开发,减少样板代码
Redux Toolkit 是当前 Redux 开发的最佳实践,它整合了多种常用的 Redux 工具和最佳实践,大大减少了样板代码,提高了开发效率。