React.js基礎入門

本文主要是針對React的一些demo教程。參考了菜鳥教程中的react教程,作了一些總結。Demo的下載連接是javascript

https://github.com/RealAndMe/react-demo

下面要講解的例子都在對應的demo中。html

從github下載react-demo須要用到的命令行:java

#下載代碼
$ git clone git@github.com:RealAndMe/react-demo.git

#安裝開發所依賴的模塊
$ npm install

#運行並監聽
$ gulp watch

#具體的能夠查看以前的相關博客

目錄結構

目錄結構

build文件夾裏是須要用到的js庫文檔react

  • jquery.js
  • react.js
  • react-dom.js
  • ……

每個demo文件夾都有
.html和.js兩個文檔,其中js文檔中放的是主要的JSX功能,html是渲染的jquery

HTML模板

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
</head>
<body>
    <div id="contain"></div>
    <script type="text/babel" src="index.js"></script>
</body>
</html>

用到的React必須的庫:git

  • react.js 是react的核心庫
  • react-dom.js 是提供與DOM相關的功能
  • browser.min.js 是將JSX語法轉換爲javascript語法。

注意:React使用獨有的JSX,與javascript不兼容,因此凡是使用JSX的地方,都要加上<script type="text/babel"></script>github

demo01

這裏.js後綴的文檔裏存放的是React的JSX語法,它是用來代替常規的javascript,執行速度更快。ajax

ReactDOM.render(<div>hello,world!</div>,document.getElementById("contain"));

ReactDOM.render()方法是將JSX轉換爲HTML方法,並將其呈現到指定的DOM節點中,是React的基本語法。算法

JSX基本語法規則:遇到HTML標籤(以 < 開頭),就用HTML規則解析;遇到代碼塊(以 { 開頭),就用JavaScript規則解析。數據庫

上面代碼是將<div>塊插入到contain的節點中(查看demo01

demo02

React.createClass()方法生成一個React組件類,類名首字母必須大寫。(查看demo02

每一個組件都有一個render : function(){}的函數,用來輸出組件,而且函數裏都有return返回值。return裏描述的就是HTML樹結構,只能包含一個頂層標籤。。

<Demo02 />實例化組件類並輸出信息。

var Demo02 = React.createClass({
    render : function(){
        return(
            <div className="demo02">hello,world!</div>
        )
    }
});
ReactDOM.render(<Demo02 />,document.getElementById("contain"));

能夠給標籤添加樣式,在html中添加類是class,可是在JSX中是calssName,而for屬性要寫成htmlFor,這是由於for和class是javascript的保留字。

demo03

在JSX中使用javascript的數組,樣式。(查看demo03

咱們能夠添加內聯樣式。React會在指定元素數字後面自動添加px。

javascript代碼塊都要用花括號{ },註釋也須要寫在花括號中。

var array = ["lilei","wangdong","yulun"];

/*定義樣式*/
var myStyle = {
    fontSize: 100,
    color: "red",
    textAlign: "center"
};

var Demo03 = React.createClass({
    render : function(){
        return(
            <div style={myStyle}>
            {/*遍歷數組*/}
            {
                array.map(function(msg,index){
                    return <div key={index}>hello,{msg}</div>
                })
            }
            </div>
        )
    }
});
ReactDOM.render(<Demo03 />,document.getElementById("contain"));

數組遍歷的時候會有警告提示表示要加上一個key屬性,這個key是用來保證react-vdom標識的惟一性。

key屬性

demo04

組件將具備屬性,可使用this.props.[attribute]來訪問,attribute是對應的屬性的名稱。

(查看demo04

var Demo04 = React.createClass({
    render : function(){
        return(
            <div>hello,{this.props.name}</div>
        )
    }
});
ReactDOM.render(<Demo04 name="wjy" />,document.getElementById("contain"));

上述代碼中就是經過this.props.name獲取組件上的name屬性。

demo05

this.props.childre屬性表示組件的全部子節點。(查看demo05

React.children.map(this.props.children,function(){})方法用來遍歷子節點的。

var Demo05 = React.createClass({
    render : function(){
        return(
            <ol>
            {
            React.Children.map(this.props.children,function(msg){
                return <li>{msg}</li>
                })
            }
            </ol>
            )
        }
});
ReactDOM.render(
    <Demo05>
        <span>你好</span>
        <span>hello,world</span>
    </Demo05>,
    document.getElementById("contain")
);

上述代碼中,組件<Demo05 />中有兩個子節點,能夠經過this.props.children來讀取。

this.props.children的值有三種狀況:

  • 當前組件沒有子節點,它的數據類型是undefined
  • 只有一個子節點,它的數據類型是object
  • 多個子節點,它的數據類型是array

因此要當心處理this.props.children屬性。

demo06

組件的屬性有不少種類型,好比:數值、字符串等,能夠經過React.propTypes來驗證props是否有效。當傳入的是無效的數據時,控制檯會拋出一個異常。(查看demo06

//var flag = "字符串類型";
var flag = 123;

var Demo06 = React.createClass({
    propTypes : {
        title : React.PropTypes.string.isRequired
    },
    render : function(){
        return(
            <h1>{this.props.title}</h1>
        )
    }
});
ReactDOM.render(<Demo06 title={flag}/>,document.getElementById("contain"));

上述代碼中,組件<Demo06 />有一個title屬性,PropType告訴React,title屬性是必須的,而且數據類型是字符串型。這裏咱們給title設置一個數值,這個時候屬性驗證不經過,控制檯會有一個異常信息。

demo07

getDefaultProps()方法是爲props設置默認值。(查看demo07

var Demo07 = React.createClass({
    getDefaultProps : function() {
        return{
            title : "wangyu"
        }
    },
    
    render : function(){
        return(
            <h1>hello,{this.props.title}</h1>
        )
    }
});
ReactDOM.render(<Demo07 />,document.getElementById("contain"));

demo08

虛擬DOM:組件並非真實的 DOM 節點,而是存在於內存之中的一種數據結構。

只有在虛擬DOM插入到文檔以後,纔會變成真實DOM。

DOM diff算法:根據 React 的設計,全部的 DOM 變更,都先在虛擬 DOM 上發生,而後再將實際發生變更的部分,反映在真實 DOM上。這樣提升了網頁的性能表現。

從組件中獲取真實的DOM節點,使用ref屬性。(查看demo08

var Demo08 = React.createClass({
    handleClick : function(){
        /*用原生的方法focus()獲取文本框焦點*/
        this.refs.textInput.focus();
    },
    render : function(){
        //  當組件插入到 DOM 後,ref 屬性添加一個組件的引用於到 this.refs,這是在真實的Dom上進行的
        return(
            <div>
                <input type="text" ref="textInput"/>
                <br/>
                <br/>
                <input type="button" value="點擊獲取焦點" onClick={this.handleClick}/>
            </div>
        )
    }
});
ReactDOM.render(<Demo08 / >, document.getElementById("contain"));

上述代碼中,<Dome08 />組件有一個文本輸入框的子節點,用來獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。爲了作到這一點,文本輸入框必須有一個 ref 屬性,而後 this.refs.[refName] 就會返回這個真實的 DOM 節點。

注意:由於 this.refs.[refName] 屬性獲取的是真實 DOM ,因此必須等到虛擬 DOM 插入文檔之後,才能使用這個屬性,不然會報錯。

上面代碼中,經過爲組件指定 Click事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件以後,纔會讀取 this.refs.[refName] 屬性。

demo09

React將組件當作是一個狀態機,一開始有一個初始狀態,而後用戶互動,致使狀態變化,從而觸發從新渲染 UI (查看demo09

var Demo09 = React.createClass({
    getInitialState: function(){
        return {like: false};
    },
    handleClick: function(){
        this.setState({like:!this.state.like});
    },
    render: function() {
        var text = this.state.like?"喜歡":"不喜歡";
        return (
            <div>
                <p>我{text}你</p>
                <input value = "點擊切換狀態" type = "button" onClick = {this.handleClick}/>
            </div>
        );
    }
});
ReactDOM.render(<Demo09 />,document.getElementById("contain"));

上述代碼中,getInitialState()方法定義state初始化的狀態,return返回的是一個對象。當用戶點擊按鈕,致使狀態改變時,this.setState({})方法用來修改state狀態值,每次修改以後,都會自行調用this.render()方法,再次渲染組件。

這個對象能夠經過this.state.[stateName]屬性來獲取,stateName是定義的狀態的名稱。

this.props 表示那些一旦定義,就再也不改變的特性,而this.state 是會隨着用戶互動而產生變化的特性。

demo10

表單組件中的value屬性(好比:<input>,<textarea>,<option>,<select>)不受任何用戶輸入的影響,若是要更新或訪問該值來響應用戶的輸入,那麼須要用onChange事件來回調。(查看demo10

var Demo10 = React.createClass({
    getInitialState: function(){
        return {
            value: "你好"
        };
    },
    handleChange: function(e){
        this.setState({value: e.target.value});
    },
    render: function(){
        var value = this.state.value;
        return (
            <div>
                <input type="text" value={value} onChange={this.handleChange} />
                <p>{value}</p>
            </div>
        );
    }
});
ReactDOM.render(<Demo10 />,document.getElementById("contain"));

上述代碼中,文本框輸入的值須要用 onChange 事件的回調函數,經過 event.target.value 讀取用戶輸入的值。textarea 元素、select元素、radio元素都屬於這種狀況

demo11

組件的生命週期有三個狀態:

  • Mounting:已插入真實的DOM
  • Updating:正在被從新渲染
  • Unmounting已移出真實的DOM

生命週期的方法總共有7種:

will函數在進入狀態以前調用,did在進入狀態以後調用。

  • componentWillMount在渲染以前調用
  • componentDidMount在第一次渲染以後調用。以後組件已經生成了對應的DOM結構,能夠經過this.getDOMNode()來進行訪問。 若是你想和其餘JavaScript框架一塊兒使用,能夠在這個方法中調用setTimeout, setInterval或者發送AJAX請求等操做(防止異部操做阻塞UI)。
  • componentWillReceiveProps組件接收到新的prop時調用,在初始化render時不調用。
  • shouldComponentUpdate組件判斷是否須要從新渲染時
  • componentWillUpdate組件在接收到新的prop或state但尚未渲染時
  • componentDidUpdate組件完成更新後調用
  • componentWillUnmount組件在DOM移出後調用
var Demo11 = React.createClass({
    getDefaultProps: function(){
        return {name: "wjy"};
    },
    getInitialState: function () {
        return {opacity: 1.0};     
    },
  componentDidMount: function () {
    setInterval(function () {
      var opacity = this.state.opacity;
      opacity -= .05;
      if (opacity < 0.1) {
        opacity = 1.0;
      }
      this.setState({
        opacity: opacity
      });
    }.bind(this), 100);
  },
  render: function () {
    return (
      <div style={{opacity: this.state.opacity}}>
        Hello {this.props.name}
      </div>
    );
  }
});
ReactDOM.render(<Demo11 />,document.getElementById("contain"));

在組件<Demo11 />加載完以後,經過該componentDidMount方法設置setInterval(function(){},time)定時器,每100ms從新設置組件透明度,而後從新渲染。(查看demo11

其中給函數加上bind(this)是爲了給當前的對象綁定事件,防止出錯

組件的樣式要注意,React 組件樣式是一個對象,因此第一重大括號表示這是 JavaScript 語法,第二重大括號表示樣式對象

style={{opacity: this.state.opacity}}   //正確寫法

demo12

React 組件的數據能夠經過 componentDidMount 方法中的 Ajax 來獲取,當從服務端獲取數據庫能夠將數據存儲在 state 中,再用 this.setState 方法從新渲染 UI。(查看demo12

var Demo12 = React.createClass({
    getInitialState: function() {
        return {
            username: '',
            lastGistUrl: ''
        };
    },
    componentDidMount: function() {
       /* 
        *jquery ajax——get()方法經過遠程HTTP GET請求載入信息,取代複雜$.ajax
       $.get(this.props.source,function(data){
            var lastGist = data[0];
            if(this.isMounted()){
                this.setState({
                    username: lastGist.owner.login,
                    lastGistUrl: lastGist.html_url
                });
            };
        }.bind(this));*/
        $.ajax({
            url: this.props.source,
            type: "get",
            success: function(data){
                var lastGist = data[0];
                if(this.isMounted()){
                    this.setState({
                        username: lastGist.owner.login,
                        lastGistUrl: lastGist.html_url
                    });
                };  
            }.bind(this)
        });
    },
    render: function() {
        return (
          <div>
            {this.state.username}用戶最新的共享地址: <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
          </div>
        );
    }
});
ReactDOM.render(<Demo12 source="https://api.github.com/users/octocat/gists"/>,document.getElementById("contain"));

$
上述代碼中,利用了jQuery的ajax()方法來獲取服務器端的數據,也能夠經過jquery的ajax的$.get(url,data,sucess(),dataType)方法經過遠程HTTP GET請求載入信息,取代複雜$.ajax。

注意:在函數中常常會用到bind(this),這裏的this指向就是componentDidMount()中的this也就是這個react對象,這樣纔可以正確訪問react屬性方法this.state,this.setState

demo13

JSX 容許直接在模板插入 JavaScript 變量。若是這個變量是一個數組,則會展開這個數組的全部成員。查看demo13

var Demo13 = React.createClass({
    render: function() {
        var array = [
            <h1>你好!</h1>,
            <h2>hello,world!</h2>
        ];
        return (
          <div>{array}</div>
        );
    }
});
ReactDOM.render(<Demo13 />,document.getElementById("contain"));

上面代碼的array變量是一個數組,結果 JSX 會把它的全部成員,添加到模板中。

有道雲筆記參考:http://note.youdao.com/noteshare?id=93e15b78b01eca521abc083659c7f356&sub=4CA29FC7AE614755889C60A513DDAF44

相關文章
相關標籤/搜索