原文地址leozdgao

之前一直在探索React相关的东西,手上有个SPA项目,于是准备上Redux试试水。Redux本身和React并没有之间的关联,它是一个通用Javscript App模块,用做App State的管理。要在React的项目中使用Redux,比较好的方式是借助react-redux这个库来做连接,这里的意思是,并不是没有react-redux,这两个库就不弄一起用了,而是说react-redux提供了一些封装,一种更科学的代码组织方式,让我们更舒服地在React的代码中使用Redux。

之前仅通过Redux文档来了解react-redux,在一段时间的实践后准备翻一翻源代码,顺便做些相关的总结。我看的代码的npm版本为v4.0.0,也就是说使用的React版本是v0.14.x。

react-redux提供两个关键模块:Provider和connect。

Provider

Provider这个模块是作为整个App的容器,在你原有的App Container的基础上再包上一层,它的工作很简单,就是接受Redux的store作为props,并将其声明为context的属性之一,子组件可以在声明了contextTypes之后可以方便的通过this.context.store访问到store。不过我们的组件通常不需要这么做,将store放在context里,是为了给下面的connect用的。

这个是Provider的使用示例:

// config app root
const history = createHistory()
const root = (  <Provider store={store} key="provider"><Router history={history} routes={routes} /></Provider>
)// render
ReactDOM.render(  root,document.getElementById('root')
)

connect

这个模块是算是真正意义上连接了Redux和React,正好它的名字也叫connect。

先考虑Redux是怎么运作的:首先store中维护了一个state,我们dispatch一个action,接下来reducer根据这个action更新state。

映射到我们的React应用中,store中维护的state就是我们的app state,一个React组件作为View层,做两件事:render和响应用户操作。于是connect就是将store中的必要数据作为props传递给React组件来render,并包装action creator用于在响应用户操作时dispatch一个action。

好了,详细看看connect这个模块做了什么。先从它的使用来说,它的API如下:

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])  

mapStateToProps是一个函数,返回值表示的是需要merge进props的state。默认值为() => ({}),即什么都不传。

(state, props) => ({  }) // 通常会省略第二个参数

mapDispatchToProps是可以是一个函数,返回值表示的是需要merge仅props的actionCreators,这里的actionCreator应该是已经被包装了dispatch了的,推荐使用redux的bindActionCreators函数。

(dispatch, props) => ({ // 通常会省略第二个参数...bindActionCreators({...ResourceActions}, dispatch)
})

更方便的是可以直接接受一个对象,此时connect函数内部会将其转变为函数,这个函数和上面那个例子是一模一样的。

mergeProps用于自定义merge流程,下面这个是默认流程,parentProps值的就是组件自身的props,可以发现如果组件的props上出现同名,会被覆盖。

(stateProps, dispatchProps, parentProps) => ({...parentProps,...stateProps,...dispatchProps
})

options共有两个开关:pure代表是否打开优化,详细内容下面会提,默认为true,withRef用来给包装在里面的组件一个ref,可以通过getWrappedInstance方法来获取这个ref,默认为false。

connect返回一个函数,它接受一个React组件的构造函数作为连接对象,最终返回连接好的组件构造函数。

然后几个问题:

React组件如何响应store的变化?
为什么connect选择性的merge一些props,而不是直接将整个state传入?
pure优化的是什么?

我们把connect返回的函数叫做Connector,它返回的是内部的一个叫Connect的组件,它在包装原有组件的基础上,还在内部监听了Redux的store的变化,为了让被它包装的组件可以响应store的变化:

trySubscribe() {  if (shouldSubscribe && !this.unsubscribe) {this.unsubscribe = this.store.subscribe(::this.handleChange)this.handleChange()}
}handleChange () {  this.setState({storeState: this.store.getState()})
}

但是通常,我们connect的是某个Container组件,它并不承载所有App state,然而我们的handler是响应所有state变化的,于是我们需要优化的是:当storeState变化的时候,仅在我们真正依赖那部分state变化时,才重新render相应的React组件,那么什么是我们真正依赖的部分?就是通过mapStateToProps和mapDispatchToProps得到的。

具体优化的方式就是在shouldComponentUpdate中做检查,如果只有在组件自身的props改变,或者mapStateToProps的结果改变,或者是mapDispatchToProps的结果改变时shouldComponentUpdate才会返回true,检查的方式是进行shallowEqual的比较。

所以对于某个reducer来说:

export default (state = {}, action) => {  return { ...state } // 返回的是一个新的对象,可能会使组件reRender// return state // 可能不会使得组件reRender
}

另外在connect的时候,要谨慎map真正需要的state或者actionCreators到props中,以避免不必要的性能损失。

最后,根据connect的API我们发现可以使用ES7 decorator功能来配合React ES6的写法:

@connect(state => ({user: state.user,resource: state.resource}),dispatch => ({...bindActionCreators({loadResource: ResourceActions.load}, dispatch)})
)
export default class Main extends Component {}

OK,结束了

React和Redux的连接react-redux【转载】相关推荐

  1. react开发教程(十)redux结合react

    描述 Redux 和 React 之间没有关系.Redux 可以搭配 React.Angular 甚至纯 JS.但是 Redux 还是比较适合和 React 搭配的,因为 React 允许你以 sta ...

  2. 【React+ts】从零开始搭建react函数式组件+router+redux+less+sass+axios反向代理+antd(保姆式教学)

    前提 你需要准备好node.js版本不低于6.14.8 和 git 文章内容比较长(保姆级别教程),全是干货,请耐心看完 通过create-react-app脚手架搭建项目 1.第一步 注: 项目名称 ...

  3. 【React+TS】从零开始搭建react+typescript+router+redux+less+px2rem自适应+sass+axios反向代理+别名@+Antd-mobile

    一.通过create-react-app脚手架创建项目 npx create-react-app testproject --template typescript 在vscode中打开项目,可以看到 ...

  4. 【React+TS】从零开始搭建react+typescript+router+redux+less+pxToVw自适应+sass+axios反向代理+别名@+Antd-mobile

    一.通过create-react-app脚手架创建项目 npx create-react-app testproject --template typescript  在vscode中打开项目,可以看 ...

  5. Redux 学习总结 (React)

    在 React 的学习和开发中,如果 state (状态)变得复杂时(例如一个状态需要能够在多个 view 中使用和更新),使用 Redux 可以有效地管理 state,使 state tree 结构 ...

  6. react 组件怎么公用_React、Redux与复杂业务组件的复用

    All State In Redux 在上一篇文章[Redux的副作用处理与No-Reducer开发模式]中,我们介绍了如何使用Redux/Redux-Saga来进行组件的状态共享,以及副作用处理. ...

  7. [Redux/Mobx] 在React中你是怎么对异步方案进行选型的?

    [Redux/Mobx] 在React中你是怎么对异步方案进行选型的? 小项目使用简单的redux-thunk方案,增加的代码量极少,只有两个api,上手成本低 大项目使用基于redux-saga的d ...

  8. react开发教程(九)redux基础

    Readux基础 什么是redux? 简单点回答就是,一个管理数据的全局对象,但是它有单一状态树的概念,所谓的单一状态树,就是指"所有的 state都以一个对象树的形式储存在一个单一的 st ...

  9. React.js 小书 Lesson5 - React.js 基本环境安装

    React.js 小书 Lesson5 - React.js 基本环境安装 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson5 转载请注明 ...

  10. react 组件构建_为React构建星级评定组件

    react 组件构建 Who doesn't love beer? When you drink a great beer you want to tell someone. You definite ...

最新文章

  1. 目标管理和任务协作,用智办事更方便
  2. AI芯片爆火 但初创公司场景落地难
  3. linux apr文件解压失败,Linux安装apache服务器遇到的问题
  4. 曼尼托巴大学计算机硕士录取要求,曼尼托巴大学硕士
  5. android 按键消息,在android中模拟键盘消息(shell命令的方法)
  6. Linux 命令之 ln -- 为文件创建链接
  7. dev的编辑器不支持getchar吗_“两头婚兴起”:你支持不娶不嫁,孩子随父姓也随母姓吗?...
  8. 阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点
  9. win10启动修复_以安全模式启动win10的4种方法,简单高效,修复电脑故障必用技巧...
  10. 应用上云2小时烧掉近50万,创始人:差点破产,简直噩梦
  11. https://sysdig.com/
  12. 2018-2019-2 网络对抗技术 20165328 Exp4 恶意代码分析
  13. Python正则表达式子模式扩展语法与应用
  14. Python模拟汉诺塔问题移动盘子的过程
  15. 日本語の勉強の日記 十七回
  16. 华为最新人事调整:余承东任智能汽车解决方案 BU CEO;美团悄悄更换抽佣规则,佣金不降反升;Scala 3 正式发布|极客头条...
  17. JNA-Java跨平台调用的利器
  18. 22_粗粒度权限控制
  19. 春季犯困易误事,是不是你?教你如何3秒清醒,春季也要注意养生
  20. 莫队算法完整总结(普通莫队、带修莫队、树上莫队、回滚莫队)

热门文章

  1. python list平均数_数据分析之Python干货笔记
  2. java类加载器用途_对于java类加载器的认识(2)
  3. Rocket - tilelink - AtomicAutomata
  4. springboot(运行原理参考借鉴)
  5. 小功能大用处 ---- 一键检测各服务器是否存活
  6. centos 7 升级python2.7 到3.5
  7. SVN配置–服务器端(linux)
  8. POJ 3862 POJ 3528 HDU 3662 HDU 4273 三维凸包问题解决模板
  9. Android消除Toast延迟显示
  10. aspf ftp_【解析】文件传输协议:FTP、TFTP、SFTP有什么区别?