前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • Vue

    • 从源码解读Vue生命周期
    • 组件的本质
    • 有状态组件的设计
    • 设计 VNode
    • 辅助创建 VNode 的 h 函数
    • 自定义渲染器和异步渲染
    • 渲染器之挂载
    • 渲染器的核心 Diff 算法
    • 渲染器之patch
    • 图解 Vue 响应式原理
    • 图解 Vue 异步更新
    • 剖析 Vue 内部运行机制
    • vue响应式原理模拟
    • vue状态管理之vuex
    • 理解Vue的设计思想及实现Vue
    • diff算法深入
    • vue router vuex原理分析
    • Vue3初探响应式原理.
    • vue2源码分析
    • vue组件化实践
  • React

  • Webpack

  • Node

  • Javascript

  • 综合

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

react结合redux实战|原理篇

文章学习导航
面试总览

30 秒速记

  • 核心判断:状态管理的核心是把状态变化约束成可追踪的数据流,中间件在派发边界扩展异步、日志和副作用
  • 原理主线:围绕 「一、定义constants」、「二、定义actionCreator」、「三、定义reducer」 建立输入、状态变化与输出之间的因果关系
  • 文章范围:讲解了如何在React项目中结合Redux进行状态管理,通过TODO应用实例,介绍了常量、action creator、reducer等核心概念及实现步骤,帮助开发者掌握React与Redux集成的实战方法。
  • 边界与代价:集中式状态不是越多越好;可变性、订阅粒度和异步取消决定性能与可维护性
  • 工程落地:选型要从状态归属、更新频率、调试需求和团队约束出发,而不是只比较 API 数量

React 结合 Redux 的关键,是让组件只负责交互和展示,把状态变化统一交给 action、reducer 与 store。 用户操作经 dispatch 发出 action,reducer 根据类型返回新状态,connect 再把所需状态和操作映射成组件属性。以 TODO 为例,列表和筛选条件可拆成两个 reducer,再用 combineReducers 合并。日志等能力放在中间件层,展示组件本身不必直接管理这些数据。

这篇文章不要按 API 清单来背。先用上面的 Mind Map 建立全局结构,再通过交互 DEMO 观察正常路径和边界路径如何改变状态;阅读正文时重点核对每一步的输入、负责执行的参与者、产生的中间状态以及最终可观察结果。遇到版本敏感结论,要把“历史实现”“当前行为”和“工程兼容策略”分开说明;遇到性能或架构取舍,则用实际指标、失败现象和验证手段支撑判断。

版本校准: 本文若分析 ReactDOM.render、旧生命周期或栈调和,应把它视为理解架构演进的历史路径。React 19 已移除 ReactDOM.render,当前客户端入口使用 createRoot;并发渲染也必须区分可中断的渲染阶段与同步提交阶段。迁移前对照 React 19 官方升级指南。

以TODO为例分析,实际开发中并不是那么简单,下面的原型只是开发中的一个原型,这个简单的例子,有助于掌握数据处理传递的原则。

# 一、定义constants

这一步不是必须的

/**
 * 常量统一保存,便于管理
 */
export const ADD_TODO = 'ADD_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO';
export const SET_VISIBILITY = 'SET_VISIBILITY';

//controll todo wheher show or hide
export const SHOW_ALL = 'SHOW_ALL';
export const SHOW_ACTIVE = 'SHOW_ACTIVE';
export const SHOW_COMPLETED = 'SHOW_COMPLETED';
@前端进阶之旅: 代码已经复制到剪贴板

# 二、定义actionCreator

/**
 * 定义action creator
 */

import * as actionType from '../constant/index';

let nextTodo = 0;

export const addTodo = (text)=>({
  type:actionType.ADD_TODO,
  id:nextTodo++,
  text
})

export const toggleTodo = (id)=>({
  type:actionType.TOGGLE_TODO,
  id
})

export const setVisibilityFilter = (filter)=>{
  return {
    type:actionType.SET_VISIBILITY,
    filter
  }
}
@前端进阶之旅: 代码已经复制到剪贴板

# 三、定义reducer

拆分reducer

  • SetVisibility.js
/**
 * 处理TODO可见与不可见的reducer
 */
import * as actionType from '../constant/index';

// 初始状态是自己设置的 后面的状态会转化
// 接收当前状态(设置默认的过滤SHOW_ALL,如设置某些选项卡的active一样),和action返回新的state
export const visibilityFilter = (state='SHOW_ALL',action)=>{
  switch(action.type) {
    case actionType.SET_VISIBILITY:
      return action.filter;
    default:
      return state;
  }
}
@前端进阶之旅: 代码已经复制到剪贴板
  • addTodo.js
/**
 * 定义处理action的reducers
 */
import * as actionType from '../constant/index';

//传入当前的状态空数、action
export const todos = (state = [],action)=>{
  switch(action.type){ // 匹配用户触发的actionType
    case actionType.ADD_TODO:
    // 合并上一次的状态和当前的状态 返回todos数组
      return [
        ...state,//把数组展开合并
        {
          id:action.id,
          text:action.text,
          completed:false//用户控制TODO是否处于点击完成的状态 默认false 没点击
        }
      ]
      // TODO列表来回切换 遍历add_todo返回的数组 通过completed来判断
    case actionType.TOGGLE_TODO:
      return state.map(todo=>(todo.id===action.id)?{...todo,completed:!todo.completed}:todo)
    default:
      return state;//匹配不到返回state
  }
}
@前端进阶之旅: 代码已经复制到剪贴板

合并reducer

/**
 * 合并reducers
 */

import { combineReducers } from 'redux'
import {todos} from './addTodo';
import {visibilityFilter} from './SetVisibility';

export default combineReducers({
  todos, //这些键其实就是被拆分的状态,后面在容器组件中需要通过connect链接
  visibilityFilter
});
@前端进阶之旅: 代码已经复制到剪贴板

# 四、定义store

import { applyMiddleware, createStore } from 'redux';
import reducer from '../reducers/index';
import logger from 'redux-logger';

// 创建store 用来存储状态
export const store = createStore(
  reducer,
  applyMiddleware(logger) //处理日志中间件
)
@前端进阶之旅: 代码已经复制到剪贴板

# 五、结合react-redux

这里忽略展示组件,完成源码看文章结尾

  • 首先我们在container组件中处理好之前分解合并的那些reducer的键,然后在通过connect链接,传递给展示组件的属性使用

容器组件处理

react-todos/src/container/FilterLink.js

// 处理数组过滤

import { connect } from 'react-redux';
import Link from '../components/Link';
import { setVisibilityFilter } from '../actions/index';

// 这里的ownProps指的是 FilterLink
// 这里的state其实就是之前分解的todos,visibilityFilter
const mapStateToProps = (state, ownProps) => {
  return {
    active:ownProps.filter === state.visibilityFilter
  }
}

/**
 如果mapDispatchToProps是一个函数,会得到dispatch和ownProps(容器组件的props对象)两个参数。
 */
const mapDispatchToProps = (dispatch, ownProps) => ({
// 这里处理对应的事件,传递给展示组件的属性
  onClick: () => {
      dispatch(setVisibilityFilter(ownProps.filter))
  }
})

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Link);
@前端进阶之旅: 代码已经复制到剪贴板
  • 分析
    • 这里通过connect组件把之前reducer处理的那些状态链接

export default combineReducers({
  todos, //这些键其实就是被拆分的状态,后面在容器组件中需要通过connect链接
  visibilityFilter
});

@前端进阶之旅: 代码已经复制到剪贴板

react-todos/src/container/VisibilityTodoList.js

← 浅析中间件Immutable总结 →

fe
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • Vue

    • 从源码解读Vue生命周期
    • 组件的本质
    • 有状态组件的设计
    • 设计 VNode
    • 辅助创建 VNode 的 h 函数
    • 自定义渲染器和异步渲染
    • 渲染器之挂载
    • 渲染器的核心 Diff 算法
    • 渲染器之patch
    • 图解 Vue 响应式原理
    • 图解 Vue 异步更新
    • 剖析 Vue 内部运行机制
    • vue响应式原理模拟
    • vue状态管理之vuex
    • 理解Vue的设计思想及实现Vue
    • diff算法深入
    • vue router vuex原理分析
    • Vue3初探响应式原理.
    • vue2源码分析
    • vue组件化实践
  • React

  • Webpack

  • Node

  • Javascript

  • 综合