React.js入门学习第一篇


Posted in Javascript onMarch 30, 2016

一、JSX介绍

①定义

JSX=JavaScript XML,是一种在React组件内部构建标签的类XML语法。React在不使用JSX的情况下一样可以工作,但是使用JSX可以提高组件的可读性,增强JS语义,结构清晰,抽象程度高,代码模块化。因此推荐在React中使用JSX。

②特点

1、元素名首字母大写

2、符合嵌套规则

3、可以写入求值表达式

4、驼峰式命名

5、不能使用javascript原生函数的一些关键词,如for和class。需要替换成htmlFor和className

③使用方法

1、使用动态值:JSX将两个花括号之间的内容{...}渲染为动态值,花括号指明了一个javascript上下文环境,花括号里面可以是一个变量,也可以是函数。 例如:

var name=“winty”;

<p>{name}</p>
function date(d){
 return [
 d.getFullYear(),
 d.getMonth()+1,
 d.getDate()
 ].join('-);
};
<p>{date(new Date()}</p>

2.注释:首先,在子节点中注释要用大括号包裹起来,然后就可以单行注释/**/,也可以多行注释//。

var Hello=React.createClass({
 render:function(){
  return <p name="winty"> //set name
   Hello ,World
   /*
   多行注释
   多行注释
   */
   </p>
  }
 });

3.使用CSS内联样式

var style={
 color:#000;
};
React.render(<div style={style}>....</div>,document.body);

4.使用条件判断

//方法1,三目运算符
var Hello=React.createClass({
 render:function(){
 return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p>
 }
});

//方法2,if-else语句
var Hello1=React.createClass({
 getName:function(){
  if(this.props.name)
  return this.props.name;
  else
  return "LuckyWinty";
 render:function(){
 return <p>Hello,{this.getName}</p>
 }
});

//方法3,使用逻辑||运算符
var Hello3=React.createClass({
 render:function(){
 return <p>Hello,{this.props.name||"LuckyWinty"}</p>
 }
});

④非DOM属性介绍

JSX中有3个非DOM属性,分别是:dangerouslySetInnerHTML、ref、key。

dangerouslySetInnerHTML:在JSX中直接插入HTML代码,但是如果能避免使用这个属性则尽量避免使用。

不合时宜的使用 innerHTML 可能会导致 cross-site scripting (XSS) 攻击。 净化用户的输入来显示的时候,经常会出现错误,不合适的净化也是导致网页攻击 的原因之一。
在彻底的理解安全问题后果并正确地净化数据之后,生成只包含唯一 key __html 的对象,并且对象的值是净化后的数据。例如:

function createMarkup() { 
 return {__html: 'First · Second'}; 
};
<div dangerouslySetInnerHTML={createMarkup()} />

ref:父组件引用子组件,你可以通过在属性中设置期望的引用名来定义一个引用。例如:

...
render:function(){
 return <div>
  <input ref="MyInput" .../>
  </div>
}
...
//然后你就可以在组件中的任何地方使用this.refs.myInput获取这个引用了

key:是一个可选的唯一标识符,通过给组件设置一个独一无二的键,并确保它在一个渲染周期中保持一致,使得React能够更只能地决定应该重用一个组件还是销毁并重建一个组件,进而提高渲染性能。例如:

var Hello3=React.createClass({
 render:function(){
 return <ul>
  <li key="1">1</li>
  <li key="2">2</li>
  <li key="3">3</li>
  </ul>
 }
});

二、React组件生命周期详解

组件本质上就是状态机,输入确定,输出一定确定。状态和结果一一对应,从而使程序变得直观。状态发生转换时会触发不同的钩子函数,从而让开发者有机会做出响应。可以用事件的思路来理解状态,但是事件与事件之间互相独立,但是不同状态之间可能会互相影响。
组件的所有状态结合起来就成了组件的生命周期。即:初始化阶段->运行中阶段->销毁阶段。 

不同生命周期内可以自定义的函数
初始化阶段:
①getDefaultProps:获取默认属性,只调用一次,是在createClass之后调用的。实例之间共享引用
②getInitialState:初始化每个实例的特有初始化状态
③componentWillMount:mout就是装载的意思,这个方法的意思就是说组件即将被装载到页面中,也是render之前最后一次修改状态的机会
④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上。只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。
⑤componentDidMount:组件被装载后才会被调用,也就是说调用这个方法的时候,组件已经被渲染到了页面上,这个时候可以修改DOM
这五个函数的执行顺序就是从上到下的。需要注意的是getDefaultProps只会在组件的第一个实例被初始化的时候被调用,也就是说第二个实例之后都是从getInitialState开始调用。同一个组件的所有实例的默认属性都是一样的。
主要测试代码:

<script type="text/babel">
 var Hello=React.createClass({
 getDefaultProps:function(){
  console.log("getDefaultProps, 1");
 },
 getInitialState:function(){
  console.log("getInitialState, 2");
  return null;
 },
 componentWillMount:function(){
  console.log("componentWillMount, 3");
 },
 render:function(){
  console.log("render, 4");
  return <p>Hi,LuckyWinty!</p>
 },
 componentDidMount:function(){
  console.log("componentDidMount, 5");
 },
 });
 React.render(<Hello></Hello>,document.body);
</script>

运行结果:

运行中阶段:React.js入门学习第一篇

①componentWillReceiveProps:这个函数在组件即将接收到属性时触发的,或者是父组件的属性发生变化时,属性在传送到组件之前,开发者有机会通过这个函数去处理属性。比如修改,更新内部状态等。
②shouldComponentUpdate:当组件接收到新属性或者新状态的时候触发的。这个是一个疑问函数,也就是说我们可以告诉react不去更新某个组件。因为有时候属性或者状态并不会导致组件发生更新。在组件不需要更新的情况下,手动使shouldComponentUpdate返回false,这样react就不需要再经过render和diff算法去判断是否要更新,从而提高性能。
③componentWillUpdate:render触发之前触发,更新组件,不能修改属性和状态
④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上,只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。
⑤componentDidUpdate:render之后,真正的DOM被渲染之后调用
备注:这五个函数的执行顺序也是从上到下的。这个的测试代码已上传至:https://github.com/LuckyWinty/ReactStudyDemo,欢迎参考!

 销毁阶段:
①componentWillUnmount:这个函数在销毁操作真正执行之前调用,给开发者最后的机会进行一些清理工作。

三、属性、状态的含义和用法

属性的含义:
props=properties,属性是不可以由组件自己进行修改的,组件的属性是由父组件传递进来的。
属性的用法:
一)、键值对

<Hello name="winty"/> 字符串
<Hello name={123}/> 大括号包裹的求值表达式
<Hello name={[1,2,3]}/> 传入数组
<Hello name={winty}/> 变量

二)、展开定义(个人认为就是对象式定义)

var props={
 one:"123",
 two:"22"
}

这样定义的话,理论上使用应该是one={props.one}这样调用,但是这样写起来比较繁琐,而且如果数据被修改,就需要对应修改相应的赋值,并且无法动态地设置属性,所以react中添加了一种展开语法:
<Hello {...props}/>    //也就是三个点加上对象名称。
这样使用展开语法,react就会自动把对象中的变量和值当作是属性的赋值,所以Hello实际上就拿到了one、two两个属性,如果没有三个点的话,Hello拿到的实际上就是props对象,使用的时候还需要自己从中取出变量和值
三)、调用react提供的setProps()函数(几乎不用)

var instance=React.render(<HelloWorld></HelloWorld>,document.body);
instance.setProps({name:"winty"});

状态的含义:
state,状态是由事物自行处理、不断变化的
状态的用法:
getInitialState:初始化实例的状态
setState:更新组件状态,一旦更新了状态,那么就会触发diff算法,检查内容是否发生变化,若有变化则更新组件,否则就不用。 

属性和状态对比
相似点:都是纯JS对象、都会触发render更新、都具有确定性。

React.js入门学习第一篇

属性和状态区分:组件在运行时需要修改的数据就是状态 

四、React中事件的用法
事件处理函数:React绑定事件处理器的方法和HTML语法非常类似,所有的事件在命名上与原生的javascript规范一致,并且会在相同的情境下触发。
编写函数
handleClick:function(){
...
}
绑定
onClick={this.handleClick} 

各类事件详细说明:
①移动设备上的触摸事件:onTouchCancel、onTouchEnd、onTouchMove、onTouchStart
②键盘类事件:onKeyDown、onKeyPress、onKeyUp
③剪切类事件:onCopy、onCut、onPaste
④表单类:onChange//内容变化即触发、onInput//输入框、onSubmit//禁止表单默认跳转行为
⑤事件:onFocus、onBlur
⑥UI元素类:onScroll
⑦鼠标滚动事件:onWheel
⑧鼠标类型:onClick、onContextMenu//右键菜单、onDoubleClick //双击、onMouseDown、onMouseEnter、onMouseLeave、onMouseMove、onMouseOut、onMouseOver、onMouseUp
⑨拖拽事件:onDrop、onDrag、onDragEnd、onDragEnter、onDragExit、onDragLeave、onDragOver、onDragStart
事件对象介绍
使用方法:就是在编写事件对象处理函数的时候,添加一个参数。拿到这个对象之后,就通过对象的属性来可以获取一些信息。
例如:

handleChange:function(event){
 console.log(event.target.value);
}

示例中,event就是事件对象,event.target就是事件对象的属性,就是对应的DOM元素,拿到这个元素之后再获取它的值。
事件对象属性
通用属性:

React.js入门学习第一篇

 其他不同类型的事件有不同的属性,简单了解一下

React.js入门学习第一篇

知道了事件的一些属性,我们就可以很方便地在React中获取这些属性,进行一些逻辑的处理,实现一些复杂的业务功能、页面效果等。

例如:我们可以利用鼠标事件属性,实时显示鼠标在某个区域的坐标:

<script type="text/jsx">
 var HelloWorld = React.createClass({
  getInitialState: function () {
  return {
   x: 0,
   y: 0
  }
  },
  handleMouseMove: function (event) {
  this.setState({
   x: event.clientX,
   y: event.clientY
  });
  },
  render: function () {
  return <div onMouseMove={this.handleMouseMove} style={{
   height: '500px',
   width: '500px',
   backgroundColor: 'gray'
  }}>
  {this.state.x + ', ' + this.state.y}
  </div>;
  },
 });
 React.render(<HelloWorld></HelloWorld>, document.body);
 </script>

x组件协同使用的定义:组件的协同本质上就是对组件的一种组织、管理方式。
组件协同使用的目的:逻辑清晰、代码模块化、封装细节、代码可复用。
组件协同使用的方式:
①组件嵌套使用:也就是说,用一个父组件把子组件包裹起来,本质就是父子关系。如下图描述:

React.js入门学习第一篇

实例代码:

var React = require('react');
var CommentList=require('./CommentList.jsx');
var CommentForm=require('./commentFrom.jsx');

var CommentBox = React.createClass({
 render: function() {
 return (
 <div className="commentBox">
 <h1>Comments</h1>
 <CommentList /> //这是一个组件
 <CommentForm /> //这是另一个组件
 </div>
 );
 }
});

module.exports = CommentBox;

父子组件之间的通信:
父组件->子组件:通过属性,父组件把数据通过属性来传递给子组件
子组件->父组件:本质上,子组件不能向父组件通信。但是可以间接地通过触发事件来通信,也就是委托。
嵌套组合缺点:
父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护
无法掌握所有细节,使用者只知道组件用法,不知道实现细节,遇到问题难以修复
②Mixin:也就是可以把相同的代码抽象出来,封装成一个函数,然后再调用。

Mixin的目的:横向抽离出组件的相似代码
相似概念:面向切向面编程、插件
实例代码:

var Time=React.createClass({
 mixins:[IntervalMixin(1000)],
 getInitialState:function(){
 return {secondElapsed:0};
 },
 onTick:function(){
 this.setState({secondElapsed:this.state.secondElapsed+1});
 },
 render:function(){
 return (
 <div>Seconds Elapsed:{this.state.secondsElapsed}</div>
 );
 }
});

mixin相当简单,它们就是混合进组件类中的对象而已。React在这方面实现得更加深入,它能防止静默函数覆盖,同时还支持多个mixin混合。但是这些功能在别的系统中可能引起冲突。例如:

React.createClass({
 mixins:[{
 getInitialState:function(){ return {a:1}}
 }],
 getInitialState:function(){ return {b:2}}
});

这样在mixin和组件类中同时定义了getInitialState方法,得到的初始state是{a:1,b:2}.如果mixin中的方法和组件类中的方法返回的对象中存在重复的键,React会抛出一个错误来警示这个问题。

 六、React中的双向绑定

React创立的理念跟angular那些框架就是不同的,React是单向数据绑定的。那么怎么实现像angular那样的双向绑定效果呢?看代码:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
 <meta charset="UTF-8">
 <title>React中的双向数据绑定</title>
</head>
<body>
 <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script>
 <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script>
 <script type="text/jsx">
 var BindingMixin = {
  handleChange: function(key) {
  var that = this
  var newState = {}
  return function(event) { 
   newState[key] = event.target.value
   that.setState(newState)
  }
  }
 }
 var BindingExample = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
  return {
   text: '',
   comment: '',
  }
  },
  render: function() {
  return <div>
   <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} />
   <textarea valueLink={this.linkState('comment')}></textarea>
   <h3>{this.state.text}</h3>
   <h3>{this.state.comment}</h3>
  </div>
  }
 })
 React.render(<BindingExample></BindingExample>, document.body);
 </script>
</body>
</html>

效果图(没有CSS样式,有点不优雅,见谅):

React.js入门学习第一篇

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
判断iframe是否加载完成的完美方法
Jan 07 Javascript
Jquery 的扩展方法总结
Oct 01 Javascript
Node.js和PHP根据ip获取地理位置的方法
Mar 14 Javascript
Js实现手机发送验证码时按钮延迟操作
Jun 20 Javascript
JavaScript实现弹出子窗口并传值给父窗口
Dec 18 Javascript
angularjs的select使用及默认选中设置
Apr 08 Javascript
浅谈React组件之性能优化
Mar 02 Javascript
在vue-cli搭建的项目中增加后台mock接口的方法
Apr 26 Javascript
如何制作一个Node命令行图像识别工具
Dec 12 Javascript
实用Javascript调试技巧分享(小结)
Jun 18 Javascript
vue 根据选择条件显示指定参数的例子
Nov 09 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 Javascript
Node.js操作mysql数据库增删改查
Mar 30 #Javascript
基于React.js实现原生js拖拽效果引发的思考
Mar 30 #Javascript
基于jQuery实现Ajax验证用户名是否存在实例
Mar 30 #Javascript
jQuery表格插件datatables用法汇总
Mar 29 #Javascript
基于javascript实现tab切换特效
Mar 29 #Javascript
基于javascript实现简单的抽奖系统
Apr 15 #Javascript
基于javascript实现九宫格大转盘效果
May 28 #Javascript
You might like
开源SNS系统-ThinkSNS
2008/05/18 PHP
PHP连接SQLSERVER 注意事项(附dll文件下载)
2012/06/28 PHP
PHP内核探索:变量存储与类型使用说明
2014/01/30 PHP
php绘图中显示不出图片的原因及解决
2014/03/05 PHP
学习PHP Cookie处理函数
2016/08/09 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
Jquery.TreeView结合ASP.Net和数据库生成菜单导航条
2010/08/27 Javascript
JS限制上传图片大小不使用控件在本地实现
2012/12/19 Javascript
JS+flash实现chrome和ie浏览器下同时可以复制粘贴
2013/09/22 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
2014/10/14 Javascript
jquery popupDialog 使用 加载jsp页面的方法
2016/10/25 Javascript
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
javascript实现小型区块链功能
2019/04/03 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
2019/08/02 Javascript
详细分析vue表单数据的绑定
2020/07/20 Javascript
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
[02:05]DOTA2完美大师赛趣味视频之看我表演
2017/11/18 DOTA
[01:13:59]LGD vs Mineski Supermajor 胜者组 BO3 第三场 6.5
2018/06/06 DOTA
Python操作CouchDB数据库简单示例
2015/03/10 Python
Python2.x中文乱码问题解决方法
2015/06/02 Python
详解Python的Django框架中Manager方法的使用
2015/07/21 Python
django模型层(model)进行建表、查询与删除的基础教程
2017/11/21 Python
python实现简单日期工具类
2019/04/24 Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
2020/01/25 Python
python统计字符的个数代码实例
2020/02/07 Python
Python Serial串口基本操作(收发数据)
2020/11/06 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
英国最大的香水商店:The Fragrance Shop
2018/07/06 全球购物
新西兰最大、占有率最高的综合性药房:PharmacyDirect药房中文网
2020/11/03 全球购物
网络安全方面的面试题
2015/11/04 面试题
办公设备采购方案
2014/03/16 职场文书
机电系毕业生求职信
2014/07/11 职场文书
2015年毕业生自荐信范文
2015/03/24 职场文书
自从在 IDEA 中用了热部署神器 JRebel 之后,开发效率提升了 10(真棒)
2021/06/26 Java/Android
阿里云服务器(windows)手动部署FTP站点详细教程
2022/08/05 Servers