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 ...
随机推荐
- java collection.sort()根据时间排序list
首先:定义bean 然后:定义比较器 最后:测试使用 一.userBean package com.butterfly.Class; public class user { private Strin ...
- 【Python】[IO编程]文件读写,StringIO和BytesIO,操作文件和目录,序列化
IO在计算机中指Input/Output,也就是输入和输出. 1.文件读写,1,读文件[使用Python内置函数,open,传入文件名标示符] >>> f = open('/User ...
- 转发 VS 重定向
转发:JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程.以前的request中存放的变量全部失效,并进入一个新的request作用域. 重定向:第一 ...
- [转]在html中控制自动换行
其实只要在表格控制中添加一句 <td style="word-break:break-all">就搞定了. 其中可能对英文换行可能会分开一个单词问题:解决如下: 语法: ...
- C++ URLDecode和URLEncode实现——仅限gb2312,非utf8
转载--http://blog.163.com/zhangjie_0303/blog/static/9908270620148251658993/ #include <iostream> ...
- Java中使用Jedis操作Redis(转载)
整理 1.字符串 添加:set keyname value 查询:get keyname 拼接:append keyname value 删除:del keyname 添加多个: mset keyna ...
- NodeJS:Error: Cannot find module 'jshint/src/cli'
以前命令:npm install gulp-jshint --save-dev 实质上是安装jshint失败,缺少该模块. 更换命令 :npm install --save-dev jshint gu ...
- git Bash常用命令
1.Construct ssh key (If you want to commit to git server via THIS COMPUTER) git config --global user ...
- Django Channels 学习笔记
一.为什么要使用Channels 在Django中,默认使用的是HTTP通信,不过这种通信方式有个很大的缺陷,就是不能很好的支持实时通信.如果硬是要使用HTTP做实时通信的话只能在客户端进行轮询了,不 ...
- XML 架构 (XSD) 参考
https://msdn.microsoft.com/zh-cn/library/ms256235.aspx XML 架构示例 XML 架构元素 XML 数据类型引用 XML 架构正则表达式 XML ...