⛏️到🚀:从原生状态管理到 Redux和React构建组件化应用

655 阅读3分钟
狗都写麻了.webp

React18 好像从现代社会走入原始社会,又走了回高速发展的今天2025。现在的我还有点回味Vue3业务思维,还没法适应React18 那种处处有DOM/JS身影中。但是还是写点东西迎接一下2025吧

下面带你从一个原生HTML和Redux配合实现的计数器出发,逐步转换到使用Redux和React实现组件化开发🤔

先聊聊为啥用Redux

我们知道,在 React 中可以使用 useStateuseReducer 解决状态管理问题。如果不够用,Context API 也能应付轻量级的跨组件通信需求。那么,为什么还需要 Redux?

Redux 是一种状态管理工具,来看看Redux 更适合的专场

  • 状态共享频繁:
    • 当组件之间需要频繁共享状态,例如用户登录信息、主题配置或表单状态。
    • Redux 提供了一个全局状态管理(store),避免了层层传递和复杂的兄弟组件通信。
  • 复杂的异步操作:
    • 当需要处理复杂的异步场景(如网络请求或异步队列)时,Redux 的中间件(如 Redux Thunk 或 Redux Saga)可以帮助更好地管理异步状态流。
  • 状态变化的可预测性:
    • Redux 强调状态的不可变性和单向数据流,所有状态更新必须通过 action -> reducer -> store 流程完成,这种模式确保了状态变化的可控性和可预测性。
  • 调试需求强:
    • Redux 的开发工具支持时间旅行调试,方便你查看每一步状态更新的过程。

一、原生HTML使用Redux

下面使用原生HTML实现计数器

核心实现思路:

  1. Reducer: 负责接收当前状态和 action,返回新的状态。状态是不可变的,每次都会生成一个新对象。
  2. Store: Redux 提供的 createStore 方法用于创建全局状态管理中心。
  3. 订阅状态变化: 使用 store.subscribe 监听状态的更新,每次状态变化时,重新渲染页面。
  4. 分发动作: 通过 store.dispatch 方法分发 action,触发状态的更新。

尽管这种方式已经脱离了直接操作 DOM,但 Redux 和 DOM 之间仍存在较高的耦合度。为了进一步提高代码的模块化和可维护性,我们可以使用 React 和 Redux 实现相同功能。

那怎么实现尼?

思考.webp

下面我们将上面的功能用 React 和 Redux 实现,代码会更加清晰、模块化。

二、引入 React 和 Redux 构建组件化计数器

1. 安装必要依赖

在项目中安装 react-reduxredux

npm install redux react-redux

2. 创建 Redux 核心逻辑

为了让状态管理更加清晰,我们将 Redux 的逻辑抽离到单独的文件中。

store.js

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

const counterSlice = createSlice({
    name: 'counter',
    initialState: { count: 0, title: '计数器' },
    reducers: {
        add(state) {
            state.count++;
        },
        sub(state) {
            state.count--;
        },
        addNum(state, action) {
            state.count += action.payload;
        },
    },
});

// 导出 actions 和 reducer
export const { add, sub, addNum } = counterSlice.actions;
export default counterSlice.reducer;

3. 编写 React 组件

Counter.js

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { add, sub, addNum } from './store';

function Counter() {
    const count = useSelector(state => state.counter.count); // 访问 Redux 状态
    const dispatch = useDispatch(); // 分发 action

    return (
        <div className="counter-container">
            <button onClick={() => dispatch(sub())}>-</button>
            <span>{count}</span>
            <button onClick={() => dispatch(add())}>+</button>
            <button onClick={() => dispatch(addNum(10))}>+10</button>
        </div>
    );
}

export default Counter;

4. 集成 Redux 和 React

使用 Provider 将 Redux 的 store 注入到 React 应用中。Provider 包裹的组件Counter因为使用了 react-redux 的连接方法(如 connect 或者 useSelectoruseDispatch 钩子),可以访问这个store 以及 state和dispatch方法

App.js

import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Counter from './Counter';

function App() {
    return (
        <Provider store={store}>
            <Counter />
        </Provider>
    );
}

export default App;

类似 Redux 这样的状态管理工具在Vue3 里面有Pinia (推荐)或 Vuex

对比 Redux

  • 状态管理流程

    • Redux:action -> reducer -> store
    • Pinia/Vuex:actions -> mutations -> state
  • 数据访问

    • Redux:通过 useSelector 读取状态。
    • Pinia/Vuex:通过 computed 或直接访问 state
  • 异步操作

    • Redux 使用中间件(Thunk、Saga)处理异步逻辑。
    • Pinia 和 Vuex 直接支持异步 actions,不需要额外中间件。