react的设计思想就是界面由数据驱动,公式:UI = f(data)。UI表明最终渲染的界面,f表示的是一个函数,data就是数据。data能够来自于组件内部的state,也能够是props。就是下文中讲到的内容。html
1、组件状态state
组件内的数据分为两种
- state 组件内部数据,外部不可见
- props 外部传入的数据
因此,判断一个数据应该放在哪里,用下面的原则:
一、若是数据由外部传入,放在 props 中;react
二、若是是组件内部状态,是否这个状态更改应该马上引起一次组件从新渲染?若是是,放在 state 中;不是,放在成员变量中。redux
如何修改state:
1 this.state.foo = 'bar'; //错误的方式
2 this.setState({foo:'bar'}); //正确的方式
如上面代码所示,若是只是修改 this.state,那改了也就只是改了这个对象,其余的什么都不会发生;若是使用 setState 函数,那不光修改 state,还能引起组件的从新渲染,在从新渲染中就会使用修改后的 state,这也就是达到根据 state 改变公式左侧 UI 的目的。
可是setState并非每次调用都能触发渲染。React为了优化渲染,避免每次setState都去渲染而浪费性能,用了任务队列的方式来解决,屡次setState调用会往队列里放多个任务,而后React会选择合适的时机去处理,当批量处理开始时,会合并多个setState,好比下面:
1 this.setState({count: 1});
2 this.setState({caption: 'foo'});
3 this.setState({count: 2});
最终会被合并为this.setState({count: 2, caption: 'foo'});因此被合并后屡次的setState只会更新一次,从而只引起一次从新渲染。固然也由于有这个队列的存在setState在React中没法保证同步更新state中的数据。注意:setState中的对象合并都是->浅合并设计模式
state的批处理:
能够这么理解,当 React 调用某个组件的生命周期函数或者事件处理函数时,React 会想:“嗯,这一次函数可能调用屡次 setState,我会先打开一个标记,只要这个标记是打开的,全部的 setState 调用都是往任务队列里听任务,当这一次函数调用结束的时候,我再去批量处理任务队列,而后把这个标记关闭。”
那么如何进行setState的连续操做并产生同步效果?使用函数式setState
setState 的第一个参数为函数时,任务列表上增长的就是一个可执行的任务函数了,React 每处理完一个任务,都会更新 this.state,而后把新的 state 传递给这个任务函数。
1 function increment(state, props) {
2 return {count: state.count + 1};
3 }
4 this.setState(increment);
5 this.setState(increment);
6 this.setState(increment);
2、Redux数据管理工具函数
Redux至关因而全部组件共享的数据store,打破了父子、子父、兄弟组件之间的数据传递的路径,均可以直接去store里拿。
适合redux的场景:
第一步,看这个状态是否会被多个 React 组件共享。
所谓共享,就是多个组件须要读取或者修改这个状态,若是是,那不用多想,应该放在 Store 上,由于 Store 上状态方便被多个组件共用,避免组件之间传递数据;若是不是,继续看第二步。
第二步,看这个组件被 unmount 以后从新被 mount,以前的状态是否须要保留。
举个简单例子,一个对话框组件。用户在对话框打开的时候输入了一些内容,不作提交直接关闭这个对话框,这时候对话框就被 unmount 了,而后从新打开这个对话框(也就是从新 mount),需求是否要求刚才输入的内容依然显示?若是是,那么应该把状态放在 Store 上,由于 React 组件在 unmount 以后其中的状态也随之消失了,要想在从新 mount 时重获以前的状态,只能把状态放在组件以外,Store 固然是一个好的选择;若是需求不要求从新 mount 时保持 unmount 以前的状态,继续看第三步。
第三步,到这一步,基本上能够肯定,这个状态能够放在 React 组件中了。
主要掌握点
- Redux 中的基本概念 action、reducer 和 store;
- 使用 react-redux 会应用哪些设计模式;
- 如何设计 Redux 的 Store。
3、Mobx数据管理工具
简单直接的数据操做,不须要作dispatch,没必要如redux走一遍严格的范式,调用action就能修改数据。并且适合使用多个store,固然使用configure配置能够禁止直接修改observable数据,只能使用action。
主要掌握点
- Mobx 的基本功能就是“观察者模式”
- decorator 是“装饰者模式”在 JavaScript 语言中的实现
- Mobx 一般利用 decorator 来使用
- 如何利用 mobx-react 来管理 React组件的状态
4、不一样方式的对比
Redux 认为,数据的一致性很重要,为了保持数据的一致性,要求Store 中的数据尽可能范式化,也就是减小一切没必要要的冗余,为了限制对数据的修改,要求 Store 中数据是不可改的(Immutable),只能经过 action 触发 reducer 来更新 Store。
Mobx 也认为数据的一致性很重要,可是它认为解决问题的根本方法不是让数据范式化,而是不要给机会让数据变得不一致。因此,Mobx 鼓励数据干脆就“反范式化”,有冗余没问题,只要全部数据之间保持联动,改了一处,对应依赖这处的数据自动更新,那就不会发生数据不一致的问题。
主要区别:
- Redux 鼓励一个应用只用一个 Store,Mobx 鼓励使用多个 Store;
- Redux 使用“拉”的方式使用数据,这一点和 React是一致的,但 Mobx 使用“推”的方式使用数据,和 RxJS 这样的工具走得更近;
- Redux 鼓励数据范式化,减小冗余,Mobx 允许数据冗余,但一样能保持数据一致。
适用场景:
Mobx 应用小而简单 快速开发
Redux 大而复杂 须要长期维护
固然随着react的不断更新发展,也有可能出现react内部的数据共享机制。