UI=render(data)
一:prop和state的对比
总结prop和state的区别:
- prop用于定义外部接口,state用于记录内部状态
- prop的赋值在外部世界使用组件时,state的赋值在组件内部
- 组件不应该改变prop的值,state存在的目的就是让组件来改变的。
this.setState()函数所做的事情,首先是改变this.state的值,然后驱动组件更新过程。
二:组件的生命周期
生命周期经历如下三个过程:
- 装载过程Mount:组件第一次在DOM树中渲染的过程。 componentWillMount componentDidMount
- 更新过程Update:当组件被重新渲染的过程 componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、componentDidupdate
- 卸载过程Unmount:组件从DOM中删除的过程 componentWillUnmount
装载过程
1、constructor
构造函数:有状态的组件才需要定义,目的是:
- 初始化state
- 绑定成员函数的this环境
2、render
render函数不做实际的渲染动作,只是然后一个JSX的描述结构,最终由React来操作渲染。render函数是一个纯函数。
更新过程
1、componentWillReceiveProps(nextProps)
只要父组件的render函数被调用,在render函数里面被渲染的子组件就会经历更新过程,不管父组件传给子组件的props有没有改变,都会触发componentWillReceiveProps函数。
通过this.setState方法触发的更新过程不会调用这个函数。
2、shouldComponentUpdate(nextProps,nextState)
render函数返回结果将用于构造DOM对象,而shouldComponentUpdate函数返回一个布尔值,告诉React库这个组件在这次更新过程中是否要继续。
通过this.setstate函数引发更新过程,并不是立刻更新组件的state值,在执行到函数shouldComponentUpdate的时候,this.state依然是this.setState函数执行之前的值。
三:组件向外传递数据
父到子组件:prop
子到父组件:将函数像其他对象一样作为prop的值从父组件传递给子组件,又可以被子组件作为函数调用。
四:Redux
React组件中state和prop的局限:state没有全局状态,prop一层一层的传递。
Redux的基本原则:
- 唯一数据源
- 保持只读状态
- 数据改变只能通过纯函数完成
1、唯一数据源
唯一数据源指的是应用的状态数据应该只存储在唯一的一个store上
2、保持状态只读
不能直接修改状态,要修改store的状态,必须要通过派发一个action对象完成。驱动用户界面渲染,就要改变应用的状态,但是改变状态的方法不是去修改状态上值,而是创建一个新的状态对象返回给Redux,由Redux完成新的状态的组装。
3、数据改变只能通过纯函数完成
reducer(state,action),redux的reducer只负责计算状态,不负责存储状态。
Redux中的每个action构造函数都返回一个action对象,action构造函数只负责创建对象,要派发action就需要调用store.dispatch函数。
五:容器组件和傻瓜组件
在Redux框架下,一个React组件基本就是完成以下两个功能:
- 外层(容器组件):和Redux Store打交道,读取Store的状态,用于初始化组件的状态,同时还要监听Store的状态改变;当Store状态发生变化时,需要更新组件状态,从而驱动组件重新渲染;当需要更新Store状态时,就要派发action对象。
- 内层(展示组件):根据当前props和state,渲染出用户界面。
1、组件Context
所谓Context,就是‘上下文环境’,让一个树状组件上所有组件都能访问一个共同的对象。Provider只是把渲染工作完全交给子组件,它扮演的只是提供Context。
2、React-Redux
改进React的两个方法:
- 把一个组件拆分为容器组件和傻瓜组件,使用connect连接。
- 使用React的Context来提供一个所有组件都可以直接访问的Context,使用Provider实现。
mapStateToProps函数:把Store上的状态转化为内层傻瓜组件的props
mapDispatchToProps函数:把内层傻瓜组件中的用户动作转化为派送给Store的动作
六:Redux中间件
Redux的单向数据流是同步操作,驱动Redux流程的是action对象,每一个action对象被派发到Store上之后,同步的被分配给所有的reducer函数,每个reducer都是纯函数,纯函数不产生任何副作用,自然是完成数据操作之后立刻同步返回,reducer返回的结果又被同步的拿去更新Store上的状态数据,更新状态数据的操作会立刻被同步给监听Store状态改变的函数,从而引发作为视图的React组件更新过程。
在Redux的单向数据流中,在action对象被reducer函数处理之前,是插入异步功能的时机。在Redux架构下,一个action对象在通过store.dispatch派发,在调用reducer函数之前,会先经过一个中间件的环节,这就是产生异步操作的机会。
使用名为middlewares的数组来存储所有的中间件,如果需要导入中间件放在middlewares数组中就可以。
异步action对象
如果没有redux-thunk中间件的存在,这样一个函数类型的action对象就被派发出来会一路发送到各个reducer函数,有了redux-thunk中间件之后,这些action对象没有机会触及到reducer函数,在中间件一层被redux-thunk截获。
redux-thunk的工作就是检查action对象是不是函数,如果不是函数就放行,完成普通action对象的生命周期,而如果发现action对象就是函数,那就执行函数,并把Store的dispatch函数和getState函数作为参数传递到函数中去,处理过程到此为止,不会让这个异步action对象继续往前派发到reducer函数。
异步action最终还是要产生同步action派发才能对Redux系统产生影响;访问服务器的异步action,无论成败,都要通过派发action对象改变Redux Store上的状态完结。
action对象被派发时,会让React组件进入各自不同的三种状态:
- 异步操作正在进行中
- 异步操作已经成功完成
- 异步操作已经失败