Post

Redux 状态管理实践

Redux 状态管理实践

什么是 Redux?

Redux 是一个基于 JavaScript 的状态容器,深受 Flux 架构启发。它通过单一数据源(Single Source of Truth)和不可变状态(Immutable State)管理应用状态。Redux 的核心理念是单一数据流,所有状态变化都通过 action 和 reducer 集中处理。

核心概念

  • Store:应用状态的单一存储,所有状态保存在这里。
  • State:Store 中的数据,描述应用当前状态。
  • Action:描述状态变化的 payload,包含 type 和可选数据。
  • Reducer:纯函数,根据 action 更新 state,返回新状态。
  • Dispatch:触发 action,更新 Store。

Redux 如何与 React 集成?

React 本身不包含内置状态管理工具,而 Redux 通过 react-redux 库与 React 集成。react-redux 提供了 <Provider> 组件和 connect 高阶组件,将 Redux Store 与 React 组件连接。

  • <Provider>:将 Store 注入 React 应用,使子组件可访问。
  • connect:将组件与 Store 绑定,映射 state 和 dispatch 到 props。

一个简单的待办事项应用示例

下面用 React 和 Redux 实现一个基本的TODO,包含添加和删除任务功能。

1. 安装依赖

1
npm install redux react-redux

2. 定义 Action Types 和 Creators

1
2
3
4
5
6
7
8
9
10
11
12
13
// actions.js
export const ADD_TODO = 'ADD_TODO';
export const DELETE_TODO = 'DELETE_TODO';

export const addTodo = text => ({
  type: ADD_TODO,
  payload: { text }
});

export const deleteTodo = id => ({
  type: DELETE_TODO,
  payload: { id }
});

3. 创建 Reducer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// reducers.js
import { ADD_TODO, DELETE_TODO } from './actions';

const initialState = {
  todos: []
};

const todoReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [
          ...state.todos,
          { id: Date.now(), text: action.payload.text }
        ]
      };
    case DELETE_TODO:
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.payload.id)
      };
    default:
      return state;
  }
};

export default todoReducer;

4. 创建 Store

1
2
3
4
5
6
7
// store.js
import { createStore } from 'redux';
import todoReducer from './reducers';

const store = createStore(todoReducer);

export default store;

5. 连接 React 组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// TodoApp.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addTodo, deleteTodo } from './actions';

class TodoApp extends Component {
  state = { inputValue: '' };

  handleInputChange = e => {
    this.setState({ inputValue: e.target.value });
  };

  handleAddTodo = () => {
    if (this.state.inputValue) {
      this.props.addTodo(this.state.inputValue);
      this.setState({ inputValue: '' });
    }
  };

  render() {
    const { todos, deleteTodo } = this.props;
    return (
      <div>
        <h1>待办事项</h1>
        <input
          value={this.state.inputValue}
          onChange={this.handleInputChange}
        />
        <button onClick={this.handleAddTodo}>添加</button>
        <ul>
          {todos.map(todo => (
            <li key={todo.id}>
              {todo.text}
              <button onClick={() => deleteTodo(todo.id)}>删除</button>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

const mapStateToProps = state => ({
  todos: state.todos
});

const mapDispatchToProps = { addTodo, deleteTodo };

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp);

6. 整合应用

1
2
3
4
5
6
7
8
9
10
11
12
13
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import TodoApp from './TodoApp';

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

7.解释

7.1 Action、Reducer 和 Store 的关系:

  • Action:是一个对象,描述状态变化的意图,包含 type(必须)和可选的 payload(数据)。例如 { type: ‘ADD_TODO’, payload: { text: ‘Learn Redux’ } } 表示添加任务。
  • Reducer:是一个纯函数,接收当前 state 和 action,根据 action.type 返回新的 state,不直接修改原状态。例如,ADD_TODO 会在 state.todos 中添加新任务。
  • Store:是 Redux 的核心,保存整个应用的 state。它通过 createStore(reducer) 创建,负责接收 action(通过 dispatch),调用 reducer 更新 state,并通知订阅者(如 React 组件)。

  • 关系
    • Action 是“指令”,告诉 Store 需要改变状态。
    • Reducer 是“规则”,定义如何根据 Action 更新 state。
    • Store 是“容器”,管理 state,调度 action 并调用 reducer。

7.2 connect 的作用:

  • connect 是 react-redux 提供的高阶组件(HOC),用于将 Redux Store 与 React 组件连接。
  • 它通过 mapStateToProps 和 mapDispatchToProps 将 Store 的 state 和 dispatch 方法映射到组件的 props。
  • 具体作用:
    • mapStateToProps(state):将 Store 的 state 映射到组件的 props(如 todos)。
    • mapDispatchToProps:将 dispatch 方法映射为组件的 props(如 addTodo)。
    • 自动订阅 Store 的变化,state 更新时触发组件重新渲染。

运行结果

  • 输入文本并点击“添加”,通过 addTodo action 更新 Store,列表显示新任务。
  • 点击“删除”按钮,触发 deleteTodo action,移除对应任务。
  • 所有状态变化都集中管理,组件只需渲染。
This post is licensed under CC BY 4.0 by the author.