1、虚拟DOM
react效率极高,它可以创建存放组件的虚拟DOM,这一特点为开发人员提供了高度灵活性和惊人的性能收益
因为React能够提前计算出DOM中有哪些内容需要更改,并对dom做出相应的更新,通过这种方式,避免了及其消耗性能的DOM 从而大幅度提高工作效率
react如何创建虚拟dom? 答:React会在内存中创建并维护一个虚拟DOM树,当数据变化时,react会自动更新虚拟dom,然后将新的虚拟dom和旧的虚拟dom进行对比, 找到变化的部分,得出一个diff,然后将diff放到一个队列里,最终批量更新这些diff,并通过render函数将更改后的虚拟dom渲染到真实的dom上。 diff算法如何进行对比? 答:即:给定任意两棵树 找到最少的转换步骤 Facebook工程师算法: 1、两个相同组件产生类似的DOM结构,不同的组件产生不同的DOM结构 2、对于同一层次的一组子节点 他们可以通过唯一的id进行区分 不同节点类型比较的时候 需要删除原先的节点 并插入一个新的节点 相同类型节点比较的时候 react会对节点属性重设 从而实现节点的转换 逐层进行节点的比较 这样只需要对树进行一次遍历 就能完成整个DOM树的比较 列表节点的比较 需要有唯一的标识 如果没有唯一的标识 react会逐个对节点进行更新 这样的话更新过程会很慢而且浪费性能 如果用key唯一标识一个节点的话可以帮助react定位到正确的节点进行比较 从而大幅减少DOM操作次数 提高性能
2.单项数据流
其实reactjs的核心内容就是数据绑定,所谓数据绑定指的是只要将一些服务端的数据和前端页面绑定好,开发者只关注实现业务就行了 单向数据流:只要服务端数据发生变动,前端数据也变动
3. 组件化开发
React的组件化开发是体现其高效率的地方
组件其实就是html,js,css,image等部分的聚合体,页面结构中独立的功能部分
组件应该拥有的性质: (1)可组合(Composeable):一个组件易于和其它组件一起使用,或者嵌套在另一个组件内部。如果一个组件内部创建了另一个组件,那么说父组件拥有(own)它创建的子组件,通过这个特性,一个复杂的UI可以拆分成多个简单的UI组件; (2)可重用(Reusable):每个组件都是具有独立功能的,它可以被使用在多个UI场景; (3)可维护(Maintainable):每个小的组件仅仅包含自身的逻辑,更容易被理解和维护 (4)可测试(Testable):因为每个组件都是独立的,那么对于各个组件分别测试显然要比对于整个UI进行测试容易的多。 划分组件的原则: 复用率高的,逻辑较为独立的
4.React组件的props和state
R数据的挂载主要依靠props和state;
1.属性(props)在组件外部传入,或者内部设置,组件内部通过this.props获得 2.状态(state)在组件内部设置或者更改,组件内部通过this.state获得 相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同) 不同点:属性能从父组件获取,状态不能 属性可以由父组件修改,状态不能 属性能在内部设置默认值 ,状态也可以 属性不在组件内部修改 ,状态要改 属性能设置子组件初始值 ,状态不可以 属性可以修改子组件的值,状态不可以 状态只和自己相关,由自己维护 属性不要自己修改,可以从父组件获取,也可以给子组件设置 组件在运行时自己需要修改的数据其实就是状态而已
5.ref
组件可以在renderdom结构中通过ref对dom、子组件进行标记 在组件里通过this.refs来获取,就可以操作真实DOM和调用子组件的属性方法
6.组件通信
(1)父 => 子 props
父:<MySecond name={'abc'} /> 子:var message = this.props.name; 若需要验证传过来数据的类型 => PropTypes属性 npm i propTypes -S import PropTypes from 'prop-types'; propTypes: { name: React.PropTypes.string.isrequired,} 其中propTypes类型有: array/bool/func/number/object/string/none/element
(2) 子 => 父
在父组件中给子组件绑定一个方法,然后在定义一个回调函数来接收子组件传过来的数据, 在子组件中通过this.props获得该方法,并传值,父组件接收到并处理 父: changeBootPage(msg) { this.setState({ bootPage: msg }); } <Start changeBootPage={this.changeBootPage.bind(this)}/> 子: this.props.changeBootPage('none')
(3)兄弟组件:
通过父组件简洁通信 或者flux 、 redux状态管理工具,实现多个组件间的数据共享