React15 - React-Redux 在React 15中的使用和工作原理
在 React 15 时代,React-Redux 的工作原理和现在(React 16.8+ Hooks时代)在核心思想上是一致的,但实现方式和使用方法有很大的不同。
在 React 15 中,React 还没有 Hooks,也没有现在的 useContext。因此,React-Redux 必须依赖两种技术来工作:
- 旧版 Context(Legacy Context):
<Provider>用来传递 store。 - 高阶组件(HOC,Higher-Order Component):
connect函数用来注入 props 和监听更新。
以下是 React 15 中 React-Redux(通常是 v4 或 v5 版本)的详细工作原理和使用方式。
⚙️ 核心工作原理(React 15 版)
1. 数据传递:旧版 Context
在 React 16.3 之前,Context API 还处于实验阶段,官方并不推荐大量使用,但 React-Redux 为了全局传递 store,不得不依赖它。
<Provider>组件:- 它实现了 React 的
getChildContext()生命周期方法。 - 将 Redux store 放到 context 对象上。
- 这样,无论组件嵌套多深,只要是有
contextTypes的组件,都能通过this.context拿到 store。
- 它实现了 React 的
2. 更新机制:订阅与强制更新
React-Redux 的核心是让组件响应 Redux store 的变化。
- 订阅(Subscription):在
connect生成的高阶组件内部,它会向 Redux store 订阅一个handleChange回调函数。 - 检查更新:当 Redux 的 state 发生变化时,store 会通知所有的订阅者。
- 浅比较(Shallow Equality):订阅者(即
connect生成的包装组件)会执行mapStateToProps函数,计算出新的 props 对象,然后和旧的 props 对象进行浅比较。 - 强制更新:如果发现数据确实发生了变化,包装组件会调用
this.forceUpdate()来强制重新渲染被包裹的 UI 组件。
3. 依赖注入:高阶组件(HOC)
connect 函数是一个高阶组件。它接收 mapStateToProps 和 mapDispatchToProps 作为参数,返回一个函数,这个函数再接收 UI 组件作为参数。
- 它从 context 中取出 store。
- 它定义
handleChange监听函数。 - 它将
state和dispatch映射成props传递给实际组件。
🛠️ 在 React 15 中的具体使用方式
因为没有 Hooks,所以必须使用 connect,并且组件必须是 Class 组件(虽然也可以写纯函数组件,但通过 HOC 包裹后最终还是 class 的逻辑)。
第一步:安装对应版本
在 React 15 项目(如老版本的 antd pro 项目)中,通常使用:
npm install react-redux@5.1.2 redux@4
第二步:创建 Store(和现在一样)
这一步变化不大,依然是使用 createStore。
// store/index.js
import { createStore } from 'redux';
// 一个简单的 reducer
const initialState = { count: 0 };
function counterReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
}
const store = createStore(counterReducer);
export default store;
第三步:使用 Provider 注入(和现在类似)
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
第四步:在 Class 组件中使用 connect(关键区别)
在 React 15 中,这是标准写法。
// components/Counter.js
import React from 'react';
import { connect } from 'react-redux';
class Counter extends React.Component {
render() {
// 从 props 中获取 redux 的状态和函数
const { count, increment } = this.props;
return (
<div>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
}
// 定义如何将 Redux state 映射到组件的 props
const mapStateToProps = (state) => {
return {
count: state.count
};
};
// 定义如何将 Redux dispatch 映射到组件的 props
const mapDispatchToProps = (dispatch) => {
return {
increment: () => dispatch({ type: 'INCREMENT' })
};
};
// connect 函数执行后返回一个新的高阶组件,包裹原来的 Counter
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
第五步:如果需要访问 store 做更复杂的操作(如异步)
在 Class 组件中,如果你需要监听 store 变化做额外的事情,可以访问 this.props.dispatch(如果不提供 mapDispatchToProps,connect 默认会注入 dispatch)。
class Counter extends React.Component {
componentDidMount() {
// 可以访问 dispatch
// this.props.dispatch(someAction());
}
// ... render
}
// 如果不传第二个参数,组件会默认收到 dispatch prop
export default connect(mapStateToProps)(Counter);
⚖️ React 15 与 React 18(Hooks 时代)的对比
为了更清晰地理解演变,这里做一个对比:
| 维度 | React 15 (React-Redux v5) | React 16.8+ (React-Redux v7+) |
|---|---|---|
| 核心 API | connect (高阶组件) |
useSelector 和 useDispatch (Hooks) |
| 组件写法 | 多为 Class 组件 | 多为函数组件 |
| 数据传递 | 旧版 Context (getChildContext / contextTypes) |
新版 Context (React.createContext) + useContext |
| 获取数据 | mapStateToProps 函数 |
useSelector Hook |
| 触发更新 | mapDispatchToProps 或 this.props.dispatch |
useDispatch Hook |
| 性能优化 | connect 自带 shouldComponentUpdate 浅比较 |
useSelector 需手动管理依赖或使用 shallowEqual |
| 代码量 | 相对繁琐,需要定义很多映射函数 | 相对简洁,直接在组件内使用 Hooks |
💡 总结:React 15 中的 React-Redux
- 工作原理:依赖旧版 Context 传递 store,通过
connect生成的高阶组件订阅 store 变化,并在数据改变时调用this.forceUpdate()触发组件重绘。 - 核心痛点:
- 模板代码多:每个组件都需要写
connect、mapStateToProps等。 - 上下文干扰:旧版 Context 有一个问题,如果中间某个组件的
shouldComponentUpdate返回 false 阻止了渲染,可能会导致 context 传递中断(虽然 React-Redux 内部通过多层订阅机制规避了此问题,但复杂度很高)。 - 对 Class 组件的强依赖:无法在函数组件中享受到 Redux 的便利,除非使用
connect包裹。
- 模板代码多:每个组件都需要写
在 React 15 时代,React-Redux 通过 connect 解决了"在 React 的单向数据流中强行加入一个全局状态树"的技术难题,是当时最优雅的解决方案。直到 Hooks 的出现,才让 Redux 的使用体验变得像今天这样简洁。

浙公网安备 33010602011771号