React学习笔记-3-非dom属性介绍
- 非dom属性?
dangerouslySetInnerHTML,ref,key
非dom标准属性,也就是说dom标准里面没有规定的属性,react引入了三个非dom属性,如上。dangerouslySetInnerHTML:字面意思,危险的设置内部html,这个属性的作用就是在jsx中,直接插入html代码。我们为什么用这个属性插入html代码呢?而不是在编写代码的时候直接写入呢?因为有的时候我们在编写代码的时候,无法确实要插入什么代码,也就是说这部分html代码是动态生成的。或者说不是由我们来编写的,为什么这中行为是危险的呢?有一个词语叫做跨站攻击,之所以会产生跨站攻击,就是因为有这样的直接写入代码功能,我们举个例子,如果页面上要显示一个内容,这个内容来自于用户的输入,假设用户的输入中包含了代码,比如说js代码,html代码,如果我们不经过检测就直接使用,把这个dom插入到页面中,那么其他人访问页面的时候,就会执行这个人写入的代码,由于我们无法判断这个用户的意图,所以他有可能写入很危险的代码,比如说添加一个连接,连接到一个木马,那么访问这个页面的用户,就会在不知不觉中中病毒或者下载木马,这是非常危险的,但是有些时候我们确实需要动态的写入代码,所以react还是提供了这个属性,只是明确的在名字里面告诉你这个属性是很危险的,尽量不要去使用。
ref:reference的缩写,父组件引用子组件,我们在编写组件的时候,经常会用到嵌套的情况,父组件如果嵌套了子组件,父组件引用子组件的时候,就需要用ref,在实际的使用中ref其实是在父组件中维护了很多引用,每一个引用都引用到了一个对应的子组件,这样我们在父组件中就可以通过这些引用来操作子组件。为什么我们不能操作父组件的父组件呢?这个其实不是代码问题,而是设计问题,在react中我们使用组件的目的就是使代码模块化,每个组件只需要考虑自己自身的功能,逻辑,不需要关心谁在使用它,因此组件不需要引用他本身的父组件,父组件和组件之间的交互式通过属性的传递来实现的,我们后面会说。但是这样的传递是单向的,也就是说,属性总是由上往下传递,下面的组件不会对上面的组件进行控制,这是为了让逻辑更加清晰,
key:提高渲染性能。react特点之一就是性能好,这是因为他去除了手动的dom操作,完全由自动来实现,但是自动实现就说明他有一套算法,也就说在页面发生变化的时候,react需要应用这套算法来判断如何高效的修改页面,以反映出对应的变化,这个算法通常被称为diff,也就是different的缩写,表示计算两个状态之间的差异。
- react diff算法

react diff算法的流程图
首先需要明确我们现在进行比较的是两个组件,react中所有的东西都是组件,所以我们只要明白了两个组件之间是如何比较的,其他的结构都可以分解成组件进行比较。
最左侧是开始,开始以后第一个判断就是节点是否相同,相同的意思就是div和div是相同的,div和p就是不同的,或者说我们自定义的HelloMessage和HelloMessage是相同的,HellowMessage 和HelloWorld就不是相同的组件,节点如果相同才会进行后面的比较,如果节点不同,react会直接抛弃旧的节点,生成一个全新的节点,在这里react是基于一个假设,如果两个节点不同,那么他们的内容很大程度不同。如果节点不同我们就直接结束比较,生成全新的节点,如果节点相同,下一步需要判断的是,这个几点是自定义的节点还是dom的标准节点,也就是说,他是div还是HelloWorld,如果说不是自定义的节点,是标准的节点,那么react下一步需要做的就是比较两个节点的属性,比如说class,id等,如果属性完全相同,就说明两个节点是相同的,结束比较;如果属性不同,就把不同的属性记下来,并应用改动,比如说多了一个新属性,就加入一个新属性,少了一个属性就删掉一个属性,类似这样的操作。也就是react并不会删掉旧的节点,只会在他上面进行操作。若果是自定义的节点,react会重新渲染他,我们后面会学习属性和状态,一个组件有很多状态,如果是同一个自定义组件,那么新组件可能只是旧组件的一个状态,所说reac会 把新的状态传入到旧的组件中,然后比较组件的渲染结果,并进行改动,也就是说react仍然不会重新生成组件,而是在旧的组件上进行改动,这就是diff算法的整个流程。那么key到底有什么用呢?key作用主要体现在节点的比较,假设我们有一个类似列表的节点,也就是父节点里面有多个子节点,那么如果没有key的时候,我们进行改动,react会比较傻的从左到右进行比较,比如说在改动之前只有节点1,在改动之后我们插入一个节点2,变成了节点2,节点1,那么react执行的操作是,删除节点1,添加节点2,添加节点1,也就是说,react无法判断新状态中的节点1是不是就状态中的节点1,所以他只能把不同的全部删掉,即使他们可能相同,这样就导致性能上的问题,那么引入key的目的就是给每个节点加上唯一的标识,这样的话react通过比较key,就可以知道到底哪些节点是原有节点,哪些节点是新加入的节点,针对我们刚才说的例子, 节点1变成了节点2节点1,这时候,react只需要做一个操作,就是插入节点2,因为节点1的key是一样的,说明他们两个是同一个节点,没有变化。
了解这个原理,对于我们编写react组件有什么启示呢?
第一点就是如果两个组件非常类似,那就尽量把他们写成一个组件,因为我们在流程中看到,两个不相同的组件一定会被重新生成,即使他们的内容非常的相似,。第二个启示就是如果使用类似的列表来展示元素的话,那么元素尽量加上key,这样可以极大地提高效率,避免不必要的性能损耗。 - 如何使用非dom属性?
dangerously的实例<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello world</title>
</head>
<body>
<script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
<script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
<script type="text/jsx">
var style={
color:"red",
border:"1px solid #f09", };
var rawHTML={
__html:"<h1>I am inner HTML</h1>"
};
var HelloWorld=React.createClass({
render: function(){
return <p>Hello,world</p>
}
});
React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>,document.body); </script>
</body>
</html>ref实例,要注意通过引用拿到的并不是这个dom节点本身,也就说我们并不能进行dom之间的操作,比如说设置文本,这样是不行的,我们拿到的只是一个虚拟的dom节点,也就是react展示给我们的dom节点,如果想要拿到真正的dom节点,还需要调用一个方法,后面我们会说,不过react并不会鼓励我们这样去做,除非在特殊的情况下,我们需要操作dom节点,其他情况react会帮助我我们进行操作,
这个例子不全,后面我们会继续讲解。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello world</title>
</head>
<body>
<script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
<script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
<script type="text/jsx">
var style={
color:"red",
border:"1px solid #f09", };
var rawHTML={
__html:"<h1>I am inner HTML</h1>"
};
var HelloWorld=React.createClass({
render: function(){
this.refs.childp return <p ref="childp">Hello,world</p>
}
});
React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>,document.body); </script>
</body>
</html>key实例:注意在每个组件的内部,key的值必须是不同的,注意是组件内部!两个组件之间就没有这个限制了。
记住两点:1,内容类似的组件尽量合并称为同一个组件,2列表类型的元素,一定要加上唯一的key,做到这两点,就能避免很多性能问题。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello world</title>
</head>
<body>
<script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
<script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
<script type="text/jsx">
var style={
color:"red",
border:"1px solid #f09", };
var rawHTML={
__html:"<h1>I am inner HTML</h1>"
};
var HelloWorld=React.createClass({
render: function(){
return
<ul>
<li key="1">1</li>
<li key="2">2</li>
<li key="3">3</li>
</ul>
}
});
React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>,document.body); </script>
</body>
</html>
React学习笔记-3-非dom属性介绍的更多相关文章
- react学习笔记1--基础知识
什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...
- React学习笔记(一)- 入门笔记
React入门指南 作者:狐狸家的鱼 本文链接:React学习笔记 GitHub:sueRimn 1.组件内部状态state的修改 修改组件的每个状态,组件的render()方法都会再次运行.这样就可 ...
- React学习笔记(六)事件处理
React学习笔记(六) 五.事件处理 React事件绑定属性的命名采用驼峰写法,不同于传统DOM全部小写. 如果采用JSX的语法,事件函数需要用大括号{}包裹函数名,不同于传统DOM字符串小括号的方 ...
- React学习笔记(五)State&声明周期
React学习笔记(五) 四.State&声明周期 可以为组件添加"状态(state)".状态与属性相似,但是状态是私有的,完全受控于当前组件. 局部状态就是只能用于类(定 ...
- React学习笔记 - 元素渲染
React Learn Note 3 React学习笔记(三) 标签(空格分隔): React JavaScript 二.元素渲染 元素是构成react应用的最小单位. 元素是普通的对象. 元素是构成 ...
- React学习笔记 - JSX简介
React Learn Note 2 React学习笔记(二) 标签(空格分隔): React JavaScript 一.JSX简介 像const element = <h1>Hello ...
- React学习笔记--程序调试
React学习笔记 二 程序调试 前面我们搭建好了React的基本开发环境,可以编写基本的React js程序了.但完成的开发环境肯定包含调试器,怎么调试用React编写的JS程序呢?有浏览器,比 ...
- React学习笔记(七)条件渲染
React学习笔记(七) 六.条件渲染 使用if或条件运算符来创建表示当前状态的元素. 可以使用变量来存储元素.比如: let button = null; if (isLoggedIn) { but ...
- React学习笔记 - 组件&Props
React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...
- React学习笔记 - Hello World
React Learn Note 1 React学习笔记(一) 标签(空格分隔): React JavaScript 前.Hello World 1. 创建单页面应用 使用Create React A ...
随机推荐
- word中方框中打钩
之前一致认为,方框打钩不可能的.今天要交评测,结果百度一下,发现可以打钩的!不会就百度(Google)真的不会错的,你所 疑虑的,可能前人已经找到解决方法!!! 解决方法: alt+9745
- 小记:目标数组的长度不够。请检查 destIndex 和长度以及数组的下限。
异常:System.ArgumentException: 目标数组的长度不够.请检查 destIndex 和长度以及数组的下限.(不好意思忘记截图了) 发生异常的代码如下: var list = ne ...
- js base64加密,后台解密
这是为了解决页面发送post请求,传输密码,在页面的控制台可以看到密码的明文,所以先用base64把要传输的密码转换为非明文,然后在后台解密处理. base64encode.js // base64加 ...
- Block产生的内存泄露,以及解决方法
前言: 在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回 ...
- ResourceHacker(4.5.30)单文件绿色汉化版
经常编译软件的人,肯定会使用一些编译和反编译的工具,ResourceHacker作为一款资源编译工具,非常的小巧好用,ResourceHacker没有任何广告,支持打开.exe..dll..scr.. ...
- Mvc视图引擎、寻址规则
目前MVC中用的较多的视图引擎应该是WebFormViewEngine和RazorViewEngine了. 一个Request请求首先会进入Routing进行判断,对于错误的url是不能被路由匹配到的 ...
- 如何根据执行计划,判断Mysql语句是否走索引
如何根据执行计划,判断Mysql语句是否走索引
- IDC机房线路质量测试方案
1.测试节点: 北京:123.206.*.* 上海:139.196.*.* 广州:119.29.*.* 汕头:125.91.*.* 香港:103.20.*.* 美国:198.52.*.* 测试服务器: ...
- CentOS个人目录下中文路径转英文路径
CentOS个人目录下中文路径转英文路径 如果安装了中文版到CentOS之后,root目录及home目录下会出现中文到路径名,如"桌面"."文档"," ...
- 调整Virtual Box硬盘大小
我在Mac下使用Virtual Box安装Win7的虚拟机.因为之前装过Win7的32位版.现在因为机器内存升到8G,就可以划出4G来支持Win7虚拟机.所以就重新安装了Win7的64位版.在创建虚拟 ...