React開發入門

目錄:
1、前言
2、什麼是React
3、開發環境搭建
4、預備知識
5、最簡單的React小程序
6、基礎語法介紹
7、總結
8、參考資料
 
1、前言
近段時間看到學長公司招聘React Native工程師,當時比較好奇,就搜索了一下,而後恰好須要每月買一本書看看,因此就買了一本《Reactive Native 開發指南》。
可是看到裏面的預備知識的時候,發現首先最好須要先了解一下React(書中寫道:咱們假設你對React已經有了一些瞭解),心想是否是還要買一本React的書籍,後來想一想幹脆直接從網上搜搜教程吧,所以開始去探索,最終找到了三個連接的內容講的React還不錯,一個是 阮一峯的博客,一個是 官方文檔,一個是 React概覽。阮一峯的博客和React概覽都是中文的,並且寫的比較容易理解,而官方文檔是英文的,講解的都比較詳細。因此若是本身英文好的話能夠直接看官方文檔。
 
2、什麼是React
React是一個JavaScript庫,是由FaceBook和Instagram開發的,主要用於用戶建立圖形化界面。
 
3、開發環境的搭建
作任何開發環境,我都會想着首先須要搭建一個環境來開發。就像若是開發iOS,你須要有蘋果電腦,而後從AppStore下載Xcode,而後就能夠熟悉一個Xcode,看看文檔,就能夠開始開發了;就像若是開發Android,你須要安裝Android Studio,而後須要安裝Java環境,而後就能夠進行開發了。對於React,通過了解,我發現任何一個工具,好比Sublime Text,IntelliJ IDEA等等均可以,你甚至直接可使用文本編輯器等等。這裏面我使用的是IntelliJ IDEA。
           一、安裝一個IntellJ IDEA就能夠進行開發了。
          二、一個瀏覽器(這裏面我使用的是Chrome)
          三、下載相關庫(下載連接
 
4、預備知識
這個博客主要是介紹的React,我也假設一下:你須要對HTML,CSS,JavaScript有必定的瞭解,由於代碼大部分都是用這些來進行開發的。
 
5、最簡單的React小程序
我學任何語言的時候第一個程序都是一個Hello,World!。如今就讓咱們來利用React來寫一個最簡單的Hello,World!
直接上代碼:
 
<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8">
   <title>Hello world!</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 = "example"></div>
   <script type="text/babel">
      ReactDOM.render(
            <h1>Hello,World!</h1>,
            document.getElementById('example')
      );
   </script>
</body>
</html>
而後用瀏覽器打開就能夠了(這裏假設你已經會使用IntellJ IDEA,若是不會就先使用Sublime Text),而後在瀏覽器裏面就能夠看到你特別熟悉的Hello,World!了。
簡單分析一下這個程序,首先,head裏面引入了三個js文件。前兩個是react的js文件,你能夠在目錄三裏面的下載相關庫裏面拿。還有一個是browser.min.js,爲何要引入這個js能夠參考這個 提問,實際上是爲了將JSX語法轉換成JavaScript語法。能夠百度谷歌一下,下載該文件,也能夠直接引用網上 資源。而後就在html裏面寫了一個script代碼塊:
<script type="text/babel">
   ReactDOM.render(
         <h1>Hello,World!</h1>,
         document.getElementById('example')
   );
</script> 
這裏須要注意:首先,/h1>後面是此外,之前 咱們可能使用的是type是text/javascript,如今咱們使用的text/babel。這是由於React獨有的JSX語法,跟JavaScript不兼容,凡是使用JSX的地方,都要加上type = 「text/babel」。
是否是已經開放蒙圈了,剛纔提了好幾個JSX,什麼是JSX呢?React官方文檔裏面的解釋是: XML語法內部包含JavaScript被叫作JSX。可是我理解的應該是咱們直接在JS裏面嵌入了HTML,這個就是React提出的叫作JSX的語法吧。這樣作的好處就是一個組件的開發過程當中,HTML是必不可少的一部分,可以將HTML封裝起來纔是組件的徹底體。JSX語法的產生,讓前端實現組件化成爲了可能。
JSX的基本語法規則:遇到HTML標籤(以<開頭),就用HTML規則解析;遇到代碼塊(以{開頭),就用JavaScript規則解析。
在ReactDOM.render裏面寫了兩行,他們的做用就是將h1標題插入example節點。
你也能夠直接新建一個js文件,而後將body裏script裏面的代碼直接放到裏面,咱們能夠命名爲helloworld.js,而後在head裏面導入便可。我比較傾向於這種作法,由於至少html文件不會看着太大,並且方便引入管理。若是其餘html也須要改代碼塊,直接引入便可。  
 
6、基礎語法介紹
一、ReactDOM.render( )
ReactDOM.render是React最基本的語法,用於將模板轉換成HTML語言,並插入指定的DOM節點。
ReactDOM.render(
    <h1>Hello,World!</h1>,
    document.getElementById('example')
);
運行結果以下:
二、map(遍歷)
將數組中的元素遍歷賦值
 
var animals = ['dog','cat','pig'];
ReactDOM.render(
    <div>
        {
            animals.map(function(animal) {
              return <h1>{animal}</h1>
            })
        }
    </div>,
    document.getElementById('example')
);
從這裏開始都是講React代碼放到了.js文件裏面,而後在html文件裏面引入。引入的時候記得寫type = ’text/babel’。這裏會有一個小問題:打開瀏覽器的調試工具後,裏面會看到Warning以下:
Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <div>
解決方法以下:
var animals = ['dog','cat','pig'];
ReactDOM.render(
    <div>
        {
            animals.map(function(animal,key) {
              return <h1 key = {key}>{animal}</h1>
            })
        }
    </div>,
    document.getElementById('example')
);
警告的意思是最好給循環產生的child添加一個key。這樣就能夠接觸警告了。運行結果以下:
這裏面你也許還會遇到另一個問題,那就是用的Sublime Text,而後太瀏覽器打開的時候提示:
 
browser.min.js:3 XMLHttpRequest cannot load file:///Users/**/***/React/MyReactDemo/helloworld/src/helloworld.js.
Cross origin requests are only supported for protocol schemes:
http, data, chrome, chrome-extension, https, chrome-extension-resource.
 實際上是由於咱們將js單獨拉出來文件致使的,可是你會發現若是使用Safari瀏覽器是沒有這個問題的。在 這裏找到了答案:
startup chrome with --disable-web-security
On Windows:

chrome.exe --disable-web-security

On Mac:

open /Applications/Google\ Chrome.app/ --args --disable-web-security
由於Chrome瀏覽器不支持本地ajax訪問。
你也能夠構建本地服務器進行訪問,好比我使用的intellJ IDEA ,直接就是在本地構建了一個本地服務,此時訪問地址爲:
http://localhost:63342/MyReactDemo/helloworld/src/helloworld.html
而沒有構建本地服務的時候訪問地址爲:
file:///Users/zhanggui/zhanggui/React/MyReactDemo/helloworld/src/helloworld.html

三、組件化javascript

由於React使用的是JSX,因此它容許將代碼封裝成組件(component),而後像普通的HTML標籤同樣插入。
React.createClass方法就是用於生成一個組件類,好比:
var ZGButton = React.createClass({
    render:function() {
        return <button>ZG{this.props.name}</button>
    }
});
ReactDOM.render(
    <ZGButton name = 'Button1'/>,
    document.getElementById('example')
);
 
運行結果以下:
上面的ZGButton就是一個組件類,模板插入<ZGButton />,會自動生成一個該組件的實例。
全部組件類都必須有本身的render方法,用於輸出組件。
如今代碼這樣寫:
var zGButton = React.createClass({
    render:function() {
        return <button>ZG{this.props.name}</button>
    }
});
ReactDOM.render(
    <zGButton name="Button2">Button</zGButton>,
    document.getElementById('example')
);
也就是將組件類的第一個字符小寫,而後在引用的時候發現如今是雙標籤了(代碼自動填充的時候出現),並且name失效。所以咱們在開發組件的時候必定要將第一個首字符大寫,不然將不會達到你想要的效果。
四、this.props.children
this.props對象的屬性和組件的屬性一一對應,可是有個children除外,它表示的是組件的全部子節點:
 
var Students = React.createClass({
    render:function() {
        return (
            <ol>
                {
                    React.Children.map(this.props.children,function(child) {
                        return <li>{child}</li>
                    })
                }
            </ol>
        );
    }
});
ReactDOM.render(
    <Students>
        <span>zhangsan</span>
        <span>lisi</span>
    </Students>,
    document.getElementById('example')
);
此時輸出的結果爲:
五、PropTypes
組件就相似與咱們OC開發或者Java開發中的類,類能夠進行屬性添加,組件也能夠。
組件的屬性能夠接受任意值,字符串、對象、函數都行。這裏面有一個propTypes,能夠用來限定提供的屬性是否知足要求:
 
var Student = React.createClass({
    propTypes: {
      myName:React.PropTypes.string.isRequired,
    },
    render:function() {
        return <h1>
            {this.props.myName}
        </h1>
    }
});
var myNameStr = "React";
ReactDOM.render(
    <Student myName = {myNameStr} />,
    document.getElementById('example')
);
這裏面的propTypes裏面的是對屬性的限制,好比這裏必須是string類型,值是必須的。咱們還能夠去設置默認屬性值:
 
var Student = React.createClass({
    getDefaultProps: function() {
        return {
            myName:"Default React"
        }
    },

    propTypes: {
      myName:React.PropTypes.string.isRequired,
    },
    render:function() {
        return <h1>
            {this.props.myName}
        </h1>
    }
});
這裏面的getDefaultProps就相似與咱們在開發iOS或者Java的時候對聲明屬性的時候進行賦初始化值。
六、Virtual DOM
組件並非真實的DOM節點,而是存在於內存中的一種數據結構,叫作虛擬DOM,只有插入文檔的時候纔會變成真實的DOM。根據React的設計,當從新渲染組件的時候,會通多diff尋找到變動的DOM節點,再把這個修改更新到瀏覽器實際的DOM節點上,因此實際上並非渲染整個DOM數,這個Virtual DOM是一個純粹的JS數據結構,性能比原生DOM快不少。這裏面咱們能夠用經過ref屬性來獲取真實的DOM屬性:
var MyComponment = React.createClass({
    render:function(){
        return (
          <div>
              <input type = "text" ref = "myTextInput"/>
              <input type = "button" value = "Focus the text input" onClick={this.handleClick}/>
          </div>
        );
    },
    handleClick:function() {
        // alert(this.refs.myTextInput);
        this.refs.myTextInput.focus();
    }
});
ReactDOM.render(
    <MyComponment/>,
    document.getElementById('example')
);
這裏須要注意的是,由於咱們使用的是真實的DOM對象,因此必定要確保DOM插入文檔以後纔可以使用。
七、this.state
咱們能夠經過this.state來拿到組件的狀態:
var LinkButton = React.createClass({
    getInitialState:function () {
      return {linked:false};
    },
    handleClick:function() {
        this.setState({linked:!this.state.linked});
    },
    render:function() {
        var text = this.state.linked? 'linked':'not linked';
        return (
            <p onClick={this.handleClick}>
                You {text} this. Click to toggle
            </p>
        );
    }
});
ReactDOM.render(
    <LinkButton/>,
    document.getElementById('example')
);
這裏面我設置了一個linked的狀態(是否鏈接),這裏經過this.state拿到當前狀態,經過this.setState來設置狀態。
八、表單
表單填寫是用戶和組件的互動:
 
var Form = React.createClass({
    getInitialState:function() {
        return {value:'Hello'};
       
    },
    handleChange:function(event) {
        this.setState({value:event.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(
    <Form/>,
    document.getElementById('example')
);
九、Component Lifecycle
組件有三個主要的生命週期:
Mounting:組件插入到DOM
Updating:組件被從新渲染,若是DOM須要更新
Unmounting:從DOM中刪除組件
React爲每一個狀態都提供了兩種處理函數,will函數在進入狀態以前調用,did在進入狀態以後調用。詳情可 參見這裏
 
var MyButton = React.createClass({

    componentDidMount:function() {
        alert("已經裝載");
    },
    componentWillMount:function() {
        alert("將要裝載");
    },
    componentWillUpdate:function() {
        alert("將要更新");
    },
    componentDidUpdate:function() {
        alert("已經更新");
    },
    componentWillUnmount:function() {
        alert("將要移除");
    },
    render:function(){
        return (
            <button>MyButton</button>
        );
    },
});
var LoadButton = React.createClass({
    loadMyButton:function() {
      ReactDOM.render(
          <MyButton/>,
          document.getElementById('myBTN')
      );
    },
    removeMyButton:function() {
        var result = ReactDOM.unmountComponentAtNode(document.getElementById('myBTN'));
        console.log(result);
    },
    render:function() {
        return (
            <div>
                <button onClick={this.removeMyButton}>卸載MyButton</button>
                <button onClick={this.loadMyButton}>裝載MyButton</button>
                <div id="myBTN">這裏是mybuttonquyu</div>
            </div>


        );
    }
});
ReactDOM.render(
    <LoadButton/>,
    document.getElementById('example')
);
十、Ajax
組件的數據一般是經過Ajax請求服務器獲取的,可使用componentDidMount方法來設置Ajax請求,等到請求成功,再用this.setState方法從新渲染UI:
 
var UserGist = React.createClass({
    getInitialState:function() {
        return {
            username:'',
            lastGistUrl:''
        }
    },
    componentDidMount:function(){
        $.get(this.props.source,function(result){
            var lastGist  = result[0];
            if (this.isMounted()) {
                this.setState({
                        username:lastGist.owner.login,
                        lastGistUrl:lastGist.html_url
                }
                );
            }
        }.bind(this));
    },
    render:function() {
        return (
            <div>

                    {this.state.username}'s last gist is
                    <a href={this.state.lastGistUrl}>here</a>

            </div>
        );
    }
});
ReactDOM.render(
    <UserGist source = "https://api.github.com/users/octocat/gists"/>,
    document.getElementById('example')
);
這裏使用了$,因此要引入jquery.js。
 
7、總結
     通過這兩天的瞭解,大概對React入門了。我的以爲React就是爲了組件化開發方便而產生的。利用React,可讓其充當MVC中V的角色。也是對MVC架構的輔助設計。
8、參考資料
  一、 阮一峯的博客
  二、 React官方文檔
  三、 React入門教程
相關文章
相關標籤/搜索