React简介:

学习地址,http://wiki.jikexueyuan.com/project/react/
一、ReactJS的背景和原理
1、ReactJS的背景
在Web开发中,我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作。而频繁的DOM操作会导致频繁的回流,影响网页性能。
2、ReactJS的原理
Diff算法:(1)节点类型不同,react直接删去旧的节点,新建一个新的节点;(2)节点类型相同,react改变需要改变的属性.
React渲染机制:在state/props发生改变的时候,重新渲染所有的节点,构造出新的虚拟Dom tree跟原来的虚拟Dom tree用Diff算法进行比较,得到需要更新的地方,再批量更新在真实的Dom上,由于这样做就减少了对Dom的频繁操作,从而提升的性能。
二、组件化
1、组件介绍
虚拟DOM(virtual-dom)不仅带来了简单的UI开发逻辑,同时也带来了组件化开发的思想,所谓组件,即封装起来的具有独立功能的UI部件。React推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义成组件,然后将小的组件通过组合或者嵌套的方式构成大的组件,最终完成整体UI的构建。
2、组件属性
ReactJS是基于组件化的开发,下面我们开始来学习ReactJS里面的组件,React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。
3、组件状态
组件要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI 。
4、书写组件时,注意事项:
A、获取属性的值用的是this.props.属性名
B、创建的组件名称首字母必须大写。
C、为元素添加css的class时,要用className。
D、组件的style属性的设置方式也值得注意,要写成style={{width: this.state.witdh}}。
三、React的优点
1、React速度很快:它并不直接对DOM进行操作,引入了一个叫做虚拟DOM的概念,安插在javascript逻辑和实际的DOM之间,性能好。
2、跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
3、一切都是component:代码更加模块化,重用代码更容易,可维护性高。
4、单向数据流:Redux是一个用于在JavaScript应用中创建单向数据层的架构,数据流动方向单一,方便管理。
四、React的缺点
React本身只是一个V,不是一个完整的框架,大型项目想要一套完整的框架的话,基本都需要加上React-Router和React-Redux才能用。
五、React子组件向父组件传值
react中state改变了,组件才会update。父组件写好state和处理该state的函数,同时将函数名通过props属性值的形式传入子组件,子组件调用父组件的函数,同时引起state变化。
六:React组件生命周期
1、实例化
(1)首次实例化
A、getDefaultProps
B、getInitialState
C、componentWillMount
D、render
E、componentDidMount
(2)实例化完成后的更新
A、getInitialState
B、componentWillMount
C、render
D、componentDidMount
2、存在期:组件已存在时的状态改变
(1)componentWillReceiveProps
(2)shouldComponentUpdate
(3)componentWillUpdate
(4)render
(5)componentDidUpdate
3、销毁&清理期
componentWillUnmount
七、webpack打包基础配置:
1、devServer:开发服务器
2、entry:入口配置
3、output:出口配置
4、module:辅助模块
5、resolve:解析方式
6、plugins: 插件
八、React创建组件的三种方式及其区别
React定义组件的三种方式:
(1)函数式定义的无状态组件
(2)es5原生方式React.createClass定义的组件
(3)es6形式的extends React.Component定义的组件
React.createClass和React.Component共同点:
(1)创建有状态的组件,
(2)组件要被实例化,
(3)可以访问组件的生命周期方法。
1、无状态函数式组件
(1)它是为了创建纯展示组件,这种组件只负责根据传入的props来展示,不涉及到要state状态的操作。具体的创建形式如下:
function HelloComponent(props, ) {
return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)
(2)无状态组件有以下几个显著的特点:
A、组件不会被实例化,整体渲染性能得到提升。
B、组件不能访问this对象
C、组件无法访问生命周期的方法
D、无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用。
2、React.createClass
React.createClass形式自身的问题:
(1)React.createClass会自绑定函数方法(不像React.Component只绑定需要关心的函数)导致不必要的性能开销,增加代码过时的可能性。
(2)React.createClass的mixins不够自然、直观;React.Component形式非常适合高阶组件(Higher Order Components--HOC),它以更直观的形式展示了比mixins更强大的功能,并且HOC是纯净的JavaScript,不用担心他们会被废弃。HOC可以参考无状态组件(Stateless Component) 与高阶组件。
3、React.Component
React.Component是以ES6的形式来创建react的组件的,可以更好实现代码复用。
九、React组件的构成
1、getInitialState() 一个用于设置最初的state的函数,返回一个对象
2、getDefaultProps() 一个用于设置默认props的函数,返回值为一个对象
3、propTypes 一个用于验证特定props类型的对象
4、mixins 组件间共享方法的途径
5、statics 一个由多个静态方法组成的对象,静态方法中不能直接调用props和state(可通过参数)
6、displayName 是一个用于命名组件的字符串,用于展示调试信息,使用JSX时将自动设置
7、componentWillMount() 在组件首次渲染前触发,只会触发一次
8、componentDidMount() 在组件首次渲染后触发,只会触发一次
9、componentWillReceiveProps() 在组件将接受新props时触发
10、shouldComponentUpdate() 组件再次渲染前触发,可用于判断是否需要再次渲染
11、componentWillUpdate() 组件再次渲染前立即触发
12、componentDidUpdate() 组件渲染后立即触发
13、componentWillUnmount() 组件卸载前立即触发
14、render() 必填,通常为一个返回React nodes或者其它组件的函数
15、React ES5和ES6的相同点
十、React ES5和ES6的不同点
来源:http://blog.csdn.net/suwu150/article/details/55805429
1、组件定义
ES5的方式:
ES6的方式: 2、propTypes、getDefaultTypes放置位置
ES6类中只允许定义方法,并不允许定义类属性。原先在 createClass 中定义的 propTypes 、 getDefaultTypes 、 displayName 、 contextTypes 等组件属性都要放到类外面来赋值。
ES5的方式:
ES6的方式: 3、手动绑定类实例到类方法(或回调函数)上
原来使用 createClass 方式创建的方法在使用的时候,默认都绑定到了它创建的组件实例上;但新版本的ES6写法上,需要按需手动绑定。
ES5的方式:
ES6的方式: 当然,你也可以在一个基类中定义一个工具方法专门用来绑定,然后子类中直接传个方法名就可以实现了,不用每次写这么多重复代码。
4、state的放置位置
ES5的getInitialState 里面的工作移到ES6的constructor 中来做。
ES5的方式:
ES6的方式: 十一、ES6的继承
Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
上面代码定义了一个ColorPoint类,该类通过extends关键字,继承了Point类的所有属性和方法。下面,我们在ColorPoint内部加上代码。 上面代码中,constructor方法和toString方法之中,都出现了super关键字,它在这里表示父类的构造函数,用来新建父类的this对象。
子类如果有constructor方法,那么必须在constructor方法中调用super方法,如果不调用super方法,子类就得不到this对象。
ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面。ES6 的实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。
子类如果没有定义constructor方法,这个方法会被默认添加,代码如下。也就是说,不管有没有显式定义,任何一个子类都有constructor方法。
另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例。 上面代码中,子类的constructor方法没有调用super之前,就使用this关键字,结果报错,而放在super方法之后就是正确的。
最后,父类的静态方法,也会被子类继承。
来源:http://es6.ruanyifeng.com/#docs/class-extends
十二、browser.js
引入browser.js的作用是使浏览器支持babel,然后才能使用ES2015(即ES6)进行编码。
十三、setState异步更新
1、setState方法通过一个队列机制实现state更新,当执行setState的时候,会将需要更新的state合并之后放入状态队列,而不会立即更新this.state.value
2、如果使用this.state.key=value来修改,将不会触发组件的render。
3、如果将this.state赋值给一个新的对象引用,那么其他不在对象上的state将不会被放入状态队列中,当下次调用setState并对状态队列进行合并时,直接造成了state丢失。
4、setState方法用于更新当前组件的state状态值,但调用这个方法后,state并不会立即更新,而是在render方法调用后才会更新,React这么设计的思想是render方法执行时,对state进行批量转变有利于DOM渲染更快。换句话说,setState方法是异步操作的,并不会阻塞下面的代码执行。
来源:http://blog.csdn.net/sysuzhyupeng/article/details/63250741
来源:http://blog.csdn.net/jqshashou/article/details/73379595
十四、React中setState同步更新策略
来源:https://segmentfault.com/a/1190000008051628
来源:http://www.jb51.net/article/129929.htm
来源:http://blog.csdn.net/u014041033/article/details/74931905
十四、怎样提高React的性能
1、将shouldComponentUpdate返回值改为true或者false以提升性能。它接受两个参数:nextProps和nextState,分别表示下一个props和下一个state的值。并且,当函数返回false时候,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染。
2、使用React.addons.Perf(React.插件.性能)来诊断缓慢或不必要的渲染。它告诉你哪里需要设置shouldComponentUpdate去减少优化你视图的更新变更次数等等。
3、key不同,不会进行diff比较,直接销毁该组件,再重建组件;key相同,不销毁该组件,只更新里面的属性; 用index做key值,在视图里移除key=3的元素,那么原来key=4的元素就会占据该位置成为key=3的元素,浏览器渲染到此,会将index=3的相关数据给这个key=3的元素,很显然这样做是错误的;解决办法:让key唯一且不可变;这是删除,增加与之类似。
这个key值是用来干嘛的呢?当我们组件状态更新后,会重新渲染组件,渲染组件的时候会一个个去根据key值的情况去渲染:
A. 渲染前的key值存在,则去寻找这个key值对应的组件:a.组件数据不变,则不重新渲染这个组件;b.若组件数据改变,则渲染改变的这一部分数据;
B.渲染前的key值不存在,则会销毁这个key值对应的组件:
C.出现新的key值,则渲染一个新的key值对应的组件;
https://www.jianshu.com/p/87f8c5344512
https://blog.csdn.net/liuzijiang1123/article/details/66974630
4、如果组件的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。例如,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。React提供的这个ref属性,表示为对组件真正实例(某部分)的引用,其实就是ReactDOM.render()返回的组件实例(的某部分)。ref属性可以设置为一个函数,这也是官方强烈推荐的用法;这个函数执行的时机为:组件被挂载后,函数被立即执行,回调函数的参数为该组件的具体实例。组件被卸载或者原有的ref属性本身发生变化时,回调也会被立即执行,此时回调函数参数为null,以确保内存泄露。
5、React通过this.state来访问state,通过this.setState()方法来更新state。当this.setState()方法被调用的时候,React会重新调用render方法来重新渲染UI
6、反模式:anti-pattern,不符合正常代码写作习惯、但理论上不算错误的程序写法。
7、反模式:在getInitialState中用Props来产生state的这种用法。这种使用方法被称之为反模式——Anti-Pattern。之所以称其为反模式是因为在getInitialState中使用Props生成state会导致重复“来源信任”问题。getInitialState函数只是在组件被第一次渲染时调用。也就是说当该组件第二次再使用render渲染的时候,getInitialState函数不会再被调用。也就是说如果我们想通过第二次渲染改变Props的值从而改变State的值是不可能的。
8、实例首次创建、实例每次创建、实例(创建后)每次渲染
9、使用props做事件处理器,与子组件通信;用state存储简单的视图状态,比如是否可见。
评论 ( 0 )
最新评论
暂无评论
赶紧努力消灭 0 回复