首先先强调一句:一定要多读官方文档,而且要精读,否则你会忽略掉很多东西!

一,Provider

刚开始看的时候,大致浏览了一下,知道了这个组件是能够接收store作为它的属性,然后它里面的子组件就可以通过props访问到store里面的所有东西了(好方便啊),然后迫不及待的写了下,发现里面的子组件的props竟然是空的(mmp),再去看一遍文档,发现,一定要用connect连接的组件才能通过props访问到store,没有用的就不能访问到了!!所以一定要看仔细了。

二,connect

connect这个函数其实最终会返回一个包着渲染组件的高阶组件。

它的基础作用如下:

1、从context里获取store

2、在componentWillMount 里通过mapStateToProps获取stateProp的值

3、在componentWillMount 里通过mapDispatchToProps获取dispatchProps的值

4、在componentWillMount 里订阅store的变化

5、将获得的stateProp,dispatchProps,还有自身的props合成一个props传给下面的组件

connect这个方法,官方的用法是:

connect([mapStateToProps], [mapDispatchToProps], [mergeProps])(MyComponent);

所以可以很明显的看出来,第一个括号里可以为空,因为都不是必选的,第二个括号里是你要连接的组件类名,所以最简单的就是

connect()(MyComponent);

这样在组件里就可以直接使用store里面的dispatch方法或者访问到store树里的state了,具体的就是this.props.dispatch()或者this.props.state()

但是这里要注意一点,connect可以不传任何参数,但是如果要使用mapDispatchToProps,就必须传mapStateToProps,否则就会报dispatch is not defined的错,如果mapStateToProps为空,可以直接传一个null

connect(null, mapDispatchToProps)(MyComponent);

接下来就是connect第一个括号里的最重要的两个参数了(mapStateToProps和mapDispatchToProps),在那之前首先弄清楚两个概念,容器组件和展示组件:

容器组件:通常是指最外层的组件,由路由直接控制的,可以使用redux,使用store,使用各种改变状态数据的方法

展示组件:通常是指拆分的小组件,它没有redux,没有store,更不会定义自己的方法,它所有的state都不会从store里面拿,而是由父组件传给他的props里拿,他的动作方法也是由props里面传的,所以它是一个比较“纯净”的组件,你传什么,他展示什么。具体的话一般都是那种复用型的组件,比如标题栏,loading组件这些。

那么什么时候才用传这两个参数,通常是展示组件connect的时候才会传这两个参数。

我们为什么要区分容器组件和展示组件?

1,分离关注,你可以更好的理解app和UI。

2,更易复用,同样的展示组件可以在不同的状态源、数据源中使用。也可以封装成容器组件,在未来重用它们。

3,展示组件是app的调色板。你可以把它们放到单独的页面,并让设计师来调整它们的样式和结构,而不用改变app的逻辑。单独的页面有静态性,你可以在上面进行screenshot regression测试。

4,这种方法会强迫你去解析布局相关的组件,比如Sidebar, Page, ContextMenu,强迫你去使用this.props.children,而非在不同容器中不断复制jsx那块地方。

三,mapStateToProps

类似于vuex里的mapState方法,具体使用直接上代码

function mapStateToProps(state) {
return {
value: state.count.value
}
}
// 此时store树里的initState结构为:
const initState = {
...
count: {
value: ""
}
...
}

那么此时我们要在当前展示组件中使用value的时候就可以通过this.props.value来访问到了,因为此时value已经绑定在了当前组件的props上面,当store里面的state变化的时候,展示组件会同步更新

四,mapDispatchToProps

类似于mapStateToProps,把当前组件所需要的动作也全部定义到props里面,因为通常动作执行的时候都需要dispatch(action),所以我们直接把动作定义好,然后组件直接用就可以了,就不用再去dispatch一个action了,mapDispatchToProps全部帮你绑好了,直接上代码

import {increaseAction} from '../actions'
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: () => dispatch(increaseAction)
}
}   

这里我们就可以直接在按钮上绑定这个方法,onClick={this.props.onIncreaseClick},如果要传参数,那就在()里面加data参数,action后面也跟一个data

要使用mapDispatchToProps必须要在connect里传递mapStateToProps,如果没有要用的,就传一个null,再说一遍!

五,bindActionCreators

这个方法是redux的,把它放在这里讲是因为它搭配mapDispatchToProps比较合适,先看一下它如何替代上面的代码:

import {increaseAction} from '../actions'
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: bindActionCreators(increaseAction, dispatch)
}
}

bindActionCreators会自动给第一个参数action执行dispatch方法,这里似乎看不出它的方便,但是试想一下,如果此时有n多个方法要定义呢,照着第一种方法,那就要写n多行的dispatch(action)了,但是如果有了bindActionCreators方法,就可以直接传一个所有actions的大对象,直接上代码:

import actions from '../actions/actionCreator'
import {bindActionCreators} from 'redux' function mapDispatchToProps(dispatch) {
return {
dispatchActions: bindActionCreators(actions, dispatch)
}
}  

这里的actions是actionCreator文件里所有的action的一个合集,那么此时要在组件中直接使用dispatch(loginAction)就可以用this.props.dispatchActions.loginAction(),有data就传data。

那什么情况下用bindActionCreators,什么时候不用只用第一种呢,我觉得看情况吧,如果当前组件的action比较多的话,可以把当前组件的所有action全部放在一个文件里,然后集体导出来,再用bindActionCreators,如果当前组件就一两个action,那我觉得没必要,直接用第一种就可以了。

redux学习日志:关于react-redux的更多相关文章

  1. React+Redux学习笔记:React+Redux简易开发步骤

    前言 React+Redux 分为两部分: UI组件:即React组件,也叫用户自定义UI组件,用于渲染DOM 容器组件:即Redux逻辑,处理数据和业务逻辑,支持所有Redux API,参考之前的文 ...

  2. React之redux学习日志(redux/react-redux/redux-saga)

    redux官方中文文档:https://www.redux.org.cn/docs/introduction/CoreConcepts.html react-redux Dome:https://co ...

  3. Redux学习(3) ----- 结合React使用

    Redux 和React 进行结合, 就是用React 做UI, 因为Redux中定义了state,并且定义了改变或获取state的方法,完全可以用来进行状态管理,React中就不用保存状态了,它只要 ...

  4. 【redux】详解react/redux的服务端渲染:页面性能与SEO

        亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)   react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...

  5. redux学习日志:关于异步action

    当我们在执行某个动作的时候,会直接dispatch(action),此时state会立即更新,但是如果这个动作是个异步的呢,我们要等结果出来了才能知道要更新什么样的state(比如ajax请求),那就 ...

  6. react+redux官方实例TODO从最简单的入门(6)-- 完结

    通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...

  7. 初学 react | redux

    react | redux 一.安装 React Redux 依赖 React 0.14或更新版本 npm install --sava react-redux 你需要使用 npm 作为包管理工具,配 ...

  8. React Redux学习笔记

    React Router React Router 使用教程 Redux中间件middleware [译]深入浅出Redux中间件 Redux学习之一:何为middleware? ES6 ES6新特性 ...

  9. react/redux组件库、模板、学习教程

    开源的有蚂蚁金服的: 1.https://pro.ant.design/index-cn 2.https://pro.ant.design/docs/getting-started-cn 3.http ...

随机推荐

  1. SpringMVC ModelAndView、Map、Model、ModelMap

    目标方法返回值可以是ModelAndView .Map.Model.ModelMap类型,但最根本还都是ModelAndView. 其中可以包含试图和模型信息. SpringMVC 会把ModelAn ...

  2. EditTable-V1.0--续集

    上一个功能有点少,这个V1.0版本是最小集合的. ================================= 双击单元格编辑,可以添加,删除单元格.并且保持相邻单元格不同的背景色. 引用了“M ...

  3. iOS libyuv

    libyuv是Google开源库,可用作图像数据格式的转换,比如视频流编解码时格式的转换,YUV数据转化RGB等 libyuv静态库 为了方便使用,已经将libyuv源代码打包成了iOS静态库,lib ...

  4. 【01背包】洛谷P1282多米诺骨牌

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

  5. 使用JavaScript 操作本地文件

    一.显示用户选择文件[图片] <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  6. CSS中水平居中的方法

    居中是我们在css中经常遇到的问题,一般有水平居中.垂直居中.垂直水平居中这3种情况,那么今天首先就来对学习到的水平居中的方法做个总结笔记. css水平居中 text-align:center 它的效 ...

  7. [转载]解决sudo: sorry, you must have a tty to run sudo

    前几天遇到一个问题,在一个终端中调用另一个shell,始终是无法执行的,后来捕捉到报错信息为sudo: sorry, you must have a tty to run sudo,后来,在网上了解到 ...

  8. [UWP]如何使用Fluent Design System (下)

    4. 兼容旧版本 FDS最常见的问题之一是如何与Fall Creators Update之前的版本兼容,其实做起来也挺简单的,ColorfulBox就实现了Creators Update与Fall C ...

  9. JavaScript es2015经验基础总结

    一.作用域 var和es6中的let 的区别. 1.var 是JavaScript中定义全局变量的关键字 2.let 是es6语法中定义变量的关键字 但是let的变量是块级作用域(只能在自己的块里面使 ...

  10. webpack基础打包安装分享

    一.创建webpack-first文件夹作为站点,创建app文件夹存放js原始模块(main.js 和 Greeter.js) 创建 public文件夹存放index.html和打包后的bundle. ...