首頁 > web前端 > js教程 > React.js入門學習第一篇_javascript技巧

React.js入門學習第一篇_javascript技巧

WBOY
發布: 2016-05-16 15:07:27
原創
2048 人瀏覽過

一、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&#63;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 &middot; 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>

登入後複製

运行结果:

运行中阶段:

①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中添加了一种展开语法:
//也就是三个点加上对象名称。
这样使用展开语法,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中事件的用法
事件处理函数: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中获取这些属性,进行一些逻辑的处理,实现一些复杂的业务功能、页面效果等。

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

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

实例代码:

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样式,有点不优雅,见谅):

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

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板