这个篇博客是对上一篇博客 React + Redux实现计算案例(优化) 的进一步优化。在上一篇博客中主要实现两个功能:1.容器组件 和 UI组件分离; 2.使用了Provider组件来提供context上下文。
其实这两个功能已经有一个库帮我们实现了,这个库就是下面将要介绍的React-Redux
这个库。
React + Redux实现计算案例(优化)这篇篇博客实现的原理与React-Redux实现的原理是一样的
1.安装React-Redux
npm install react-redux@5.0.7 --save//在react-redux-sample项目下安装react-redux,并指定版本
2.引入React-Redux中的Provider
上一篇博客编写的Provider与React-Redux库提供的Provider实现的原理是一样的
换了了Provider , 执行的还是可以的:
3.修改容器组件的写法
Counter.js 容器组件的写法:
1.从react-redux
中导入connect
函数, 该函数用来创建容器组件
2.mapStateToProps()
函数负者将state状态树中的数据
传递给UI组件
Counter。
import React, { Component } from 'react';
import CounterItem from './CounterItem'
/**从react-redux中导入connect函数,该函数用来创建容器组件*/
import {connect} from 'react-redux';
const style = {
width:'200px',
backgroundColor:'skyblue',
margin: '20px'
};
/*1.UI组件:只负责UI的呈现*/
var Counter=({sum})=>(
<div style={style}>
<CounterItem id={0}></CounterItem>
<CounterItem id={1}></CounterItem>
<div>
合计:<span>{sum}</span>
</div>
</div>
)
/**
* 将状态树中的数据 传递 到UI组件Counter中
* @param state 状态树中的数据
* @param ownProps 当前这个CounterContainer容器组件接收到的props参数
* @returns {{value: number}} 传递给UI组件的props
*/
function mapStateToProps(state,ownProps) {
let sum = 0;
state.forEach(function (item,index) {
sum+=item.number
})
/*这个sum将会被 传递 到UI组件Counter的props中*/
return {sum: sum};
}
/*2.容器组件:负者管理数据和逻辑*/
var CounterContainer=connect(mapStateToProps)(Counter);
export default CounterContainer;
CounterItem.js容器的写法:
1.从react-redux
中导入connect
函数, 该函数用来创建容器组件
2.mapStateToProps()
函数负者将state状态树中的数据
传递给UI组件
CounterItem。
3.mapDispatchToProps()
函数负者将分发事件的函数
传递给UI组件
CounterItem
import React, { Component } from 'react';
import * as Actions from '../action';
/**从react-redux中导入connect函数,该函数用来创建容器组件*/
import {connect} from 'react-redux';
const style = {
margin:'10px'
};
/*1.UI组件:只负责UI的呈现*/
var CounterItem=({num,addCounter,removeCounter})=>(
<div style={style}>
<button onClick={addCounter}> + </button>
<span>{num}</span>
<button onClick={removeCounter}> - </button>
</div>
)
/**
* 将状态树中的数据 传递 到UI组件CounterItem中
* @param state 状态树中的数据
* @param ownProps 当前这个CounterItemContainer容器组件接收到的props参数
* @returns {{value: number}} 传递给UI组件的props
*/
function mapStateToProps(state,ownProps) {
var num=state[ownProps.id].number;
/*这个num将会被 传递 到UI组件CounterItem的props中*/
return {num: num};
}
/**
* 将有分发事件的函数 传递 到UI组件CounterItem中
* @param dispatch
* @param ownProps 当前这个CounterItemContainer容器组件接收到的props参数
* @returns {{onIncrement: (function()), onDecrement: (function())}}
*/
function mapDispatchToProps(dispatch, ownProps) {
/*这个addCounter 和 removeCounter 函数将会被 传递 到UI组件CounterItem的props中*/
return {
addCounter: () => {
/*负者分发addCounter事件*/
dispatch(Actions.addCounter(ownProps.id));
},
removeCounter: () => {
/**ownProps.id : 是获取CounterItemContainer容器组件接收的props参数*/
dispatch(Actions.removeCounter(ownProps.id));
}
}
}
/*2.容器组件:负者管理数据和逻辑*/
var CounterItemContainer=connect(mapStateToProps,mapDispatchToProps)(CounterItem);
export default CounterItemContainer;
修改后还是可以执行: