React简介:

原创 前端工程师_钱成 随笔 React 408阅读 2017-12-04 13:05:59 举报

一、ReactJS的背景和原理(真实DOM和虚拟DOM)
1、所有浏览器的引擎工作流程都大致分5步:创建DOMtree–>创建StyleRules->构建Rendertree->布局Layout–>绘制Painting。用原生api或jQuery操作DOM”一次“,浏览器会从构建DOM树开始,把这5步从头到尾执行”一遍“。

2、比如一次(点击)事件执行时,需要更新10个DOM节点,理想状态是一次性构建完DOM树,再执行后续操作。但浏览器没这么智能,收到第一个更新DOM请求后,并不知道后续还有9次更新操作,因此会马上执行流程,最终执行10次流程。显然例如计算DOM节点的坐标值等都是白白浪费性能,可能这次计算完,紧接着的下一个DOM更新请求,这个节点的坐标值就变了,前面的一次计算是无用功。
3、虚拟DOM就是为了解决这个浏览器性能问题而被设计出来的。一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地的一个js对象中,最终将这个js对象一次性attach到DOM树上,通知浏览器去执行绘制工作,这样可以避免大量的无谓的计算量。
来源:https://www.jianshu.com/p/616999666920
在页面一开始打开的时候,React会调用render函数构建一棵Dom树,在state/props发生改变的时候,render函数会被再次调用渲染出另外一棵树,接着,React会用对两棵树进行对比,找到需要更新的地方批量改动。
二、React的缺点和优点
1、缺点:React本身只是一个V,不是一个完整的框架,大型项目想要一套完整的框架的话,基本都需要加上React-Router和React-Redux才能用。
2、优点:(1)单向数据流动;(2)虚拟DOM取代物理DOM作为操作对象;(3)用JSX语法取代HTML模板,在JavaScript里声明式地描述UI。
三、react组件间的传值
(1)react父组件向子组件传值:实例是一个对象,在父实例定义一个函数(也可以是属性),在这个函数的函数体里,将这个函数的参数赋值给父实例的一个状态;然后通过属性传参的方式把这个函数传给子实例。在子实例里,给这个函数传参并执行,实现父组件向子组件传值!
(2)react子组件向父组件传值:实例是一个对象,在父组件定义一个函数,给这个函数绑定父组件的this,在这个函数的函数体里,将这个函数的参数赋值给父组件实例的一个状态;然后通过属性传参的方式把这个函数传给子组件。在子组件里,给这个函数传参并执行,实现子组件向父组件传值!这是利用回调函数来实现的,也可以利用自定义事件来实现。
(3)跨级组件通信

(4)没有嵌套关系的组件通信

四:React组件生命周期
1、实例化
(1)实例首次被创建,即第一次调用<element attr="" />
A、getDefaultProps
B、getInitialState
C、componentWillMount
D、render
E、componentDidMount
(2)实例再次被创建,即后来调用<element attr="" />
A、getInitialState
B、componentWillMount
C、render
D、componentDidMount
2、存在期:组件已存在时的状态改变,即在完整调用一次<element attr="" /> 的过程中,它内部的state的变化。props是组件外面传入的数据,state是组件内部私有的数据。React组件的数据是一个“从上到下”的“单向”数据流。所有组件的state(状态)就如同一个额外属性汇入主流props(属性),且只能随着主流的方向向下流动。
(1)componentWillReceiveProps
(2)shouldComponentUpdate
(3)componentWillUpdate
(4)render
(5)componentDidUpdate
3、销毁&清理期
componentWillUnmount
五、React创建组件的三种方式及其区别
1、React定义组件的三种方式:
(1)函数式定义的无状态组件
(2)es5原生方式React.createClass定义的组件
(3)es6形式的extendsReact.Component定义的组件
React.createClass和React.Component共同点:
(1)创建有状态的组件,
(2)组件要被实例化,
(3)可以访问组件的生命周期方法。
2、无状态函数式组件:创建纯展示组件,这种组件只负责根据传入的props来展示,不涉及到要state状态的操作。无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用。
六、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() 必填,通常为一个返回Reactnodes或者其它组件的函数
七、为什么不能用index做key?
key不同,不会进行diff比较,直接销毁该组件,再重建组件;key相同,不销毁该组件,只更新里面的属性;用index做key值,在视图里移除key=3的元素,那么原来key=4的元素就会占据该位置成为key=3的元素,浏览器渲染到此,会将index=3的相关数据给这个key=3的元素,很显然这样做是错误的;解决办法:让key唯一且不可变;这是删除,增加与之类似。
八、React组件的数据(props和state)
props是组件外面传入的数据,state是组件内部私有的数据。React组件的数据是一个“从上到下”的“单向”数据流。所有组件的state(状态)就如同一个额外的水源汇入props(属性)主流,且只能随着主流的方向向下流动。
九、受控组件:表单元素输入值受React控制的组件为“受控组件”。<inputtype="text">,<textarea>和<select>都接受一个value属性来实现受控组件。
十、JSX(在React下,不用JS操作DOM而用JSX来创建组件,使得代码简单、层次清晰)
1、React不一定要用JSX,只用JavaScript也可以。但使用JSX可以让我们开发更加高效,代码更加简洁。
2、JSX即JavaScriptXML,是一种在React组件内部构建标签的类XML语法。
3、JSX并不是一门新的语言,仅仅是个语法糖(syntacticsugar),允许开发者在JavaScript中书写HTML语法。最后,每个HTML标签都转化为JavaScript代码来运行。
4、这样对于使用JavaScript来构建组件以及组件之间关系的应用,在代码层面显得更加清晰。而不再像过于一样用JavsScript操作DOM来创建组件以及组件之间的嵌套关系。
5、JSX必须借助ReactJS环境才能运行,所以使用前要先加载ReactJS文件(react.js、react-dom.js)除了ReactJS环境,还需要加载JSX的解析器(browser.js)
原文链接:http://www.hangge.com/blog/cache/detail_1472.html
十一、React 组件
React 组件基本上由 3 个部分组成——属性(props)、状态(state)以及生命周期方法。React 组件可以接收参数(即改变props),也可能有自身状态。一旦接收到的参数(即props)或自身状态有所改变,React 组件就会执行相应的生命周期方法,最后渲染。整个过程完全符合传统组件所定义的组件职责(“属性更新”与“状态改变”)。以上内容来自《深入React技术栈》第18页。“更新过程”指的是父组件向下传递 props 或组件自身执行setState 方法时发生的“一系列更新”。以上内容来自《深入React技术栈》第30页。
动作。
十二、ref可以设置回调函数
ref属性可以设置为一个回调函数,这也是官方强烈推荐的用法;这个函数执行的时机为:
组件被挂载后,回调函数被立即执行,回调函数的参数为该组件的具体实例。
组件被卸载或者原有的ref属性本身发生变化时,回调也会被立即执行,此时回调函数参数为null,以确保内存泄露。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复