说明:阅读本篇文章须要对Redux有必定的了解,对Redux不了解的同窗可先看看这篇文章Redux技术架构简介(一)html
为了让Redux和React更好的配合,Facebook专门开发了一个npm包--react-redux,能够这样引入你的项目:
npm install --save react-redux
固然不引用也彻底能够(Redux包是必需要引用的),只不过会增长一些开发量,还会带来一些额外的性能开销。react
Redux的React绑定库的基本开发思想是展现组件与容器组件相分离。展现组件只负责页面呈现,不处理数据,不维护状态;容器组件负责页面的运行逻辑,获取展现组件中的消息,处理内部数据,更新状态等。 npm
React引入redux后,应用中只有单一的state树,react的每一个组件均可以抛弃state的相关逻辑,改成从props获取,包括要执行的一些用户事件行为。
引入redux后的react组件变为:redux
class MainContent extends React.Component{
constructor(props){
super(props);
this.sortResult = this.sortResult.bind(this);
this.showSlider = this.showSlider.bind(this);
}
sortResult(data){
this.props.setPhoto(data);
}
showSlider(index){
this.props.showSlider(index);
}
componentDidMount () {
this.props.fetchPosts();
}
render(){
let {isFetching, isValidate} = this.props;
let sliderNode = null;
if(this.props.photo.length){
sliderNode = <PhotoSliderContainer data={this.props.photo} />;
}
return (
<div className="mainContent">
<Header title="photo" />
<SortContainer data={this.props.photo} sortResult={this.sortResult}/>
<PhotoItemsContainer data={this.props.photo} showSlider = {this.showSlider}/>
{sliderNode}
</div>
);
}
};
复制代码
能够看到,MainContent组件除了展现外,几乎没有任何的逻辑处理(subscribe和dispatch的逻辑都放到了容器组件),全部的数据都是经过this.props从父组件中获取。bash
容器组件实现了将展现组件和redux关联在一块儿。技术上讲,容器组件就是使用 store.subscribe() 从 Redux state 树中读取部分数据,并经过 props 来把这些数据提供给要渲染的组件。建议每一个展现组件对应一个容器组件,这样能够很清晰的找到映射关系。架构
从名字上能够看出,这个函数实现了从state(reducer中定义的)到展现组件props 的映射。示例代码以下:ide
const mapStateToProps = (state, ownProps) => {
return {
photo : state.photomainReducer.photoData,
video : state.photomainReducer.videoData,
isFetching : state.photomainReducer.isFetching,
isValidate : state.photomainReducer.isValidate
}
}
复制代码
传入的state是应用中惟一的状态树,咱们从相应组件的reducer中读取state,分别映射到一个自定义属性中,这样就能够在展现组件中直接调用对应属性(props)了。
mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,从新计算 UI 组件的参数,从而触发 UI 组件的从新渲染。函数
一样咱们也能够猜到,这个函数的做用是将指望执行的dispatch方法的返回值映射到展现组件的props上。示例代码以下:post
const mapDispatchToProps = (dispatch, ownProps) => {
return {
slider:(data) => dispatch(photomainAction.showSlider(data))
}
}
复制代码
好比咱们想dispatch一个showSlider的action,经过这个方法映射以后,就能够直接这样写:性能
this.props.slider(data)
复制代码
即mapDispatchToProps封装了dispatch方法。此外,还能够经过redux提供的bindActionCreators函数进一步封装,上面的代码能够改写以下:
const mapDispatchToProps = (dispatch, ownProps) => {
return bindActionCreators({
slider:photomainAction.showSlider
},dispatch);
}
复制代码
若是import时的action名和你想定义的属性名同样,甚至还能够简化:
const mapDispatchToProps = (dispatch, ownProps) => {
return bindActionCreators({slider},dispatch);
}
复制代码
上面2个方法实现了state和action到props的映射,咱们还须要把这2个函数链接在一块儿,而且要关联到一个具体的展现组件,这样就能够在展现组件中使用这种映射关系了。示例代码以下:
const PhotomainContainer = connect(
mapStateToProps,
mapDispatchToProps
)(Photomain);
复制代码
其中,Photomain是一个展现组件。 每个容器组件都包含一个对应的展现组件,咱们能够把这些容器组件当作一个普通的react组件进行组合,整合的最后一步就是如何把store传入到每一个组件中。
Store保存了整个应用的单一状态树,全部容器组件都须要从store中读取,咱们能够store做为属性传递给每一个组件,子组件经过props获取,可是若是嵌套过深,写起来会很麻烦。还好,react-redux提供一个叫provider的组件,他可让全部组件均可以访问到store(他的实现原理其实是利用了react的context功能),而没必要显示的一层层传递了。
ReactDOM.render(
<Provider store={store}>
<PhotomainContainer></PhotomainContainer>
</Provider>,
$(".main-wrap")[0]
);
复制代码
有一点要注意,provider内的组件只能有一个,因此须要将全部组件先封装成一个组件再用provider包裹起来。
Redux的引入使React完全脱离了对数据状态的管理,可让React更专一于View的展示,实际上这也是react善于作的事情。单独看react,咱们甚至感受不到redux的存在,使逻辑层和视图层更加清晰(redux负责逻辑,react负责视图),固然一部分缘由要归功于react-redux包作了很好的封装。
以上就是React与Redux整合的简单实现。