Redux 入门超详细指南
实习时突然遇到一个问题,一个页面中用到了将近 10 个组件,传参传来传去复杂得很,所以就有了这篇临时学习的 Redux 入门指南。
一、非常重要的 引言
在介绍什么是 Redux 前,我想先来介绍一下为什么我们要用到 Redux。这就不得不从 React 的本质上面说起。
1.1 React组件树的本质限制
在没有 Redux 之前,React 组件之间传递数据就像下面这样:
But,问题来了,为什么数据不能从 组件A 直接 传到 组件D,为什么中间要经过中转站呢?注意,此处,React 基础非常好的同学可自动跳过 第一节 非常重要的引言(狗头)
1.1.1 React的数据流规则
React有一个 单向数据流 的核心原则:
数据只能从 父组件 传递给 子组件
兄弟组件之间 不能直接通信
子组件 不能直接 向父组件传递数据(除了通过回调函数)
1.1.2 组件树结构示例
假设我们有这样的组件树结构:
App (根组件)├── Header│ └── UserInfo (组件A - 有用户数据)├── MainContent│ ├── Sidebar (组件B - 中转站)│ └── ProductList│ └── ProductCard (组件D - 需要用户数据)└── Footer
1.2 为什么不能直接从A传给D?
1.2.1 组件树层级关系
// 组件A和组件D在不同的分支上App├── Header│ └── UserInfo (A) ❌ 不能直接到达 ProductCard (D)└── MainContent └── ProductList └── ProductCard (D)
A和D不是直接的父子关系,React的props只能沿着父→子的路径传递
1.2.2 具体代码演示
// 这样是不可能的 - A不能直接传给Dfunction UserInfo() { // 组件A const userData = { name: \"张三\", id: 123 }; // 无法直接传递给ProductCard组件! // // 这里访问不到ProductCard}function ProductCard() { // 组件D // 无法直接接收UserInfo的数据 // const userData = ???; // 从哪里获取?}
1.2.3 React的设计哲学
React被设计为:
组件封装:每个组件只知道自己的直接子组件
单向数据流:数据向下流动,事件向上冒泡
可预测性:数据流向清晰,便于调试
二、为什么需要 Redux ?
2.1 什么是 Redux?
Redux 是一个用于 JavaScript 应用程序的状态管理库。想象一下,如果你的应用是一个大型商场,Redux 就像是商场的中央控制室,负责管理整个商场的所有信息(比如库存、顾客信息、营业状态等)。
在没有 Redux 之前,React 组件之间传递数据就像下面这样:
有了 Redux 之后,就像这样:
2.2 Redux 的核心概念
Redux 有三个核心概念,我们用一个简单的比喻来理解:
2.2.1 Store(仓库)
Store 就像一个大仓库,存放着应用的所有状态数据
// 创建一个简单的storeconst store = { count: 0, user: { name: \'张三\', age: 25 }}
2.2.2 Action(动作)
Action 就像一张说明书,告诉 Redux \"我想要做什么\"。
// 增加计数的actionconst incrementAction = { type: \'INCREMENT\' // 必须有type属性}// 设置用户名的actionconst setNameAction = { type: \'SET_NAME\', payload: \'李四\' // 携带数据}
2.2.3 Reducer(处理器)
Reducer 是一个函数,接收当前状态和 action,返回新的状态。
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 }}
2.3 Redux 的工作流程
2.3.1 工作流程图
2.3.2 简单的计数器例子
// 1. 定义初始状态const initialState = { count: 0}// 2. 创建 Reducerfunction counterReducer(state = initialState, action) { switch (action.type) { case \'INCREMENT\': return { count: state.count + 1 } case \'DECREMENT\': return { count: state.count - 1 } default: return state }}// 3. 创建 Storeconst store = Redux.createStore(counterReducer)// 4. 订阅状态变化store.subscribe(() => { console.log(\'当前计数:\', store.getState().count)})// 5. 发送 Actionstore.dispatch({ type: \'INCREMENT\' }) // 计数变为 1store.dispatch({ type: \'INCREMENT\' }) // 计数变为 2store.dispatch({ type: \'DECREMENT\' }) // 计数变为 1
2.4 Redux 三大原则
2.5 Redux vs 其他状态管理方案
2.6 Redux 的优缺点总结
优点
可预测性:状态变化完全可预测,便于调试
集中管理:所有状态集中在一个地方
时间旅行:可以回溯到任何历史状态
强大的开发工具:Redux DevTools 提供强大的调试功能
中间件支持:可以轻松添加日志、异步处理等功能
缺点
学习曲线陡峭:概念较多,初学者需要时间理解
代码量大:需要写很多样板代码
过度工程:对于简单应用可能过于复杂
性能开销:每次状态变化都会触发重新渲染
什么时候使用 Redux?