ReactJS入門

標(biāo)簽:前端開發(fā) ReactJS


官網(wǎng)
官網(wǎng)中文鏡像(推薦)
阮一峰老師的教程
菜鳥網(wǎng)的教程
一看就懂的ReactJS入門教程(語法有點(diǎn)過期了)

關(guān)鍵庫:
react.js; react-dom.js; browser.min.js;


前言: ReactJS產(chǎn)生的原因背景

在Web開發(fā)中,我們總需要將變化的數(shù)據(jù)實(shí)時反應(yīng)到UI上玫锋,這時就需要對DOM進(jìn)行操作。而復(fù)雜或頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因(如何進(jìn)行高性能的復(fù)雜DOM操作通常是衡量一個前端開發(fā)人員技能的重要指標(biāo))庵楷。React為此引入了虛擬DOM(Virtual DOM)的機(jī)制:在瀏覽器端用Javascript實(shí)現(xiàn)了一套DOM API冯乘。基于React進(jìn)行開發(fā)時所有的DOM構(gòu)造都是通過虛擬DOM進(jìn)行内斯,每當(dāng)數(shù)據(jù)變化時栋猖,React都會重新構(gòu)建整個DOM樹净薛,然后React將當(dāng)前整個DOM樹和上一次的DOM樹進(jìn)行對比,得到DOM結(jié)構(gòu)的區(qū)別蒲拉,然后僅僅將需要變化的部分進(jìn)行實(shí)際的瀏覽器DOM更新肃拜。而且React能夠批處理虛擬DOM的刷新痴腌,在一個事件循環(huán)(Event Loop)內(nèi)的兩次數(shù)據(jù)變化會被合并,例如你連續(xù)的先將節(jié)點(diǎn)內(nèi)容從A變成B燃领,然后又從B變成A士聪,React會認(rèn)為UI不發(fā)生任何變化,而如果通過手動控制猛蔽,這種邏輯通常是極其復(fù)雜的剥悟。盡管每一次都需要構(gòu)造完整的虛擬DOM樹,但是因?yàn)樘摂MDOM是內(nèi)存數(shù)據(jù)曼库,性能是極高的区岗,而對實(shí)際DOM進(jìn)行操作的僅僅是Diff部分,因而能達(dá)到提高性能的目的毁枯。這樣慈缔,在保證性能的同時,開發(fā)者將不再需要關(guān)注某個數(shù)據(jù)的變化如何更新到一個或多個具體的DOM元素种玛,而只需要關(guān)心在任意一個數(shù)據(jù)狀態(tài)下藐鹤,整個界面是如何Render的。
如果你像在90年代那樣寫過服務(wù)器端Render的純Web頁面那么應(yīng)該知道赂韵,服務(wù)器端所要做的就是根據(jù)數(shù)據(jù)Render出HTML送到瀏覽器端娱节。如果這時因?yàn)橛脩舻囊粋€點(diǎn)擊需要改變某個狀態(tài)文字,那么也是通過刷新整個頁面來完成的祭示。服務(wù)器端并不需要知道是哪一小段HTML發(fā)生了變化肄满,而只需要根據(jù)數(shù)據(jù)刷新整個頁面。換句話說绍移,任何UI的變化都是通過整體刷新來完成的悄窃。而React將這種開發(fā)模式以高性能的方式帶到了前端讥电,每做一點(diǎn)界面的更新蹂窖,你都可以認(rèn)為刷新了整個頁面。至于如何進(jìn)行局部更新以保證性能恩敌,則是React框架要完成的事情瞬测。


1.代碼生成標(biāo)簽,插入到指定位置

jsx/babel語言 JS,HTML混寫

<body>  
   <div id="example"></div>  
   <script type="text/babel">     
    ReactDOM.render(
       <h2>Hello,world</h2>, 
      document.getElementById('example')
    );  
    </script>
</body>

div#example 作為容器存放生成的元素纠炮,
生成元素:ReactDOM.render(<tag>{codehere}</tag>, container);

注意:語句結(jié)尾可以不加分號月趟,不會出錯,有些語句加了分號之后就會出錯恢口,因此加分號要小心孝宗。


2.自定義標(biāo)簽(組件)

<script type="text/babel"> 
var MyTag = React.createClass({  
    render:function(){ return<h1>{this.props.name}</h1> }  
 }); //this.props.xxx 調(diào)用自定義屬性;
ReactDOM.render(<MyTag name="zhe" />, document.getElementById('example') );  
</script> 

自定義標(biāo)簽要一定要用在render中,直接用在html無效耕肩。
后面demo為了方便就不寫ReactDOM.render()了因妇,實(shí)際練習(xí)時要加上
注意類名一定要首字母大寫问潭,createClass參數(shù)是一個對象,
添加組件屬性婚被,有一個地方需要注意狡忙,對于要調(diào)用class屬性與for屬性,屬性名不能直接寫 class 或者for址芯,這是因?yàn)?class 和 for 是 JavaScript 的保留字灾茁。用className="" htmlFor=""代替,這樣css一樣可以.class找到該元素


3.可嵌套子元素的自定義標(biāo)簽

<script type="text/babel">
var MyList = React.createClass({  
     render:function(){ 
         return( 
          <ul>{ React.Children.map(this.props.children,
                 function(child){return<li>{child}</li>} ) }</ul>
         )} //注意大小寫谷炸,props.children 用于獲取子元素
});

// 使用
// <MyList> 
//  <span>item1</span> 
//  <span>item2</span>
//</MyList> 

</script>

一種映射的方法:array.map(function(item){console.log(item)})遍歷array每次輸出一個item北专。
另外如果數(shù)組是一系列標(biāo)簽,可以寫在容器標(biāo)簽內(nèi)自動展開,如<div>{array}</div>旬陡。
React.Children.map該方法遍歷children逗余,而不用理會children因size不同(0,1,1+)而返回的不同類型(undefine,object, array)


4. 組件的參數(shù)檢查與默認(rèn)值

<script type="text/babel">
var MyTag = React.createClass({   
    getDefaultProps: function(){ return {title:"hello"}  }, //默認(rèn)值   
    propTypes: {title: React.PropTypes.string.isRequired }, //表示title是必須,并且是字符串  
    render: function(){ return<h1>{this.props.title}</h1>} 
});

//<MyTag title={123} /> 控制臺報錯季惩,但一樣會顯示在頁面

</script>



5. 獲取組件內(nèi)部標(biāo)簽的DOM節(jié)點(diǎn)

內(nèi)部標(biāo)簽定義一個ref屬性录粱,組件使用this.refs.xxx內(nèi)獲取節(jié)點(diǎn)

var MyInput = React.createClass({
    clickEvent:function(){ this.refs.tagInside.focus() }, //clickEvent的名字可隨意   
    render:function(){ return(
       <div>
         <input type="text" ref="tagInside"/>
         <input type="button" value="focus" onClick={this.clickEvent} />
       </div> )  
     }
});


6. 組件的狀態(tài)this.state

標(biāo)記組件的狀態(tài),用于改變顯示的文字画拾,樣式等啥繁。

var MyInput = React.createClass({
    getInitialState: function(){ return { liked: false } },//定義應(yīng)有的狀態(tài)與初始化,用鍵值對形式   
    clickEvent:function() { this.setState({liked: !this.state.liked }) },//this.setState({}) 改變狀態(tài)值   
    render:function() { 
       var text =this.state.liked ? "liked" : "unliked"; 
       return<input type="button" value={text} onClick={this.clickEvent} />    
    }
});

每次setState后都會自動調(diào)用render,因此可以改變樣式青抛。
注意this.state與this.props的區(qū)別旗闽,state可以在交互中改變,可讀可寫蜜另,props定義了了就不能改變适室,只讀。


7. 獲取表單的輸入

輸入表單屬于交互举瑰,改變this.state

var MyInput = React.createClass({
    getInitialState: function() { return {value: "default"} },   
    changeEvent:function(e) { this.setState({value: e.target.value}) },   
    render:functiion(){ return( 
      <div>  
        <input type="text" value={text} onChange={this.changeEvent} />    
        <p> {text}</p> 
      </div> )  
    } //注意大小寫
});

因?yàn)槊看胃淖儬顟B(tài)都會調(diào)用render,因此如果input里的value設(shè)為常數(shù)捣辆,那么輸入文本就不會顯示改變


8. 組件的生命周期

分為 mounting: 已插入到真實(shí)的DOM中;
updating:被渲染中此迅;
unmounting 已經(jīng)移出真實(shí)的DOM
有兩種回調(diào)函數(shù):will 在進(jìn)入某一步前調(diào)用汽畴,did進(jìn)入某一步后調(diào)用,共5個

componentWillMount();
componentDidMount();
componentWillUpdate(oNextProps, oNextState);
componentDidUpdate(oPrevProps, oPrevState);
componentWillUnmount();

這個比較復(fù)雜耸序,還是看官網(wǎng)比較好:https://facebook.github.io/react/docs/working-with-the-browser.html#component-lifecycle


9. AJAX

componentDidMount 中可以用jQuery.get() 實(shí)現(xiàn)忍些,React 本身沒有任何依賴,完全可以不用jQuery坎怪,而使用其他庫罢坝。

<script type="text/babel">
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.body
);
</script>

10. 傳入promise對象

<script type="text/babel">
    var RepoList = React.createClass({
        getInitialState: function() {return {loading:true, data:null, error:null}},
        componentDidMount: function() {
            this.props.promise.then(
                value => this.setState({loading:false, data:value}),
                error => this.setState({loading:false, error:error})
            )
        },
        render: function(){
            if (this.state.loading) {
                return <span>loading...</span>
            } else if (this.state.error) {
                return <span>Error: {this.state.error.message} </span>
            } else {
                var repos = this.state.data.items;
                var list = repos.map(function(repo){
                    return (
                        <li> 
                            <a href={repo.html_url}> {repo.name} </a>
                             ({repo.stargazers_count} stars) <br/> 
                             {repo.description}
                        </li> ) 
                })
            }
            return (<div>
                      <h1>Most Popular JavaScript Projects in Github</h1>
                      <ol>{list}</ol>
                    </div>)

        }

    })

    ReactDOM.render(
        <RepoList promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')} />,
        document.getElementById("example")
    )
    </script>

總結(jié)

上面是react的簡單用法,更多更詳細(xì)的解釋請看官方文檔搅窿。
react還可以配合flux框架使用嘁酿,接下來可以學(xué)習(xí)這方面的相關(guān)知識疾棵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市痹仙,隨后出現(xiàn)的幾起案子是尔,更是在濱河造成了極大的恐慌,老刑警劉巖开仰,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拟枚,死亡現(xiàn)場離奇詭異,居然都是意外死亡众弓,警方通過查閱死者的電腦和手機(jī)恩溅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谓娃,“玉大人脚乡,你說我怎么就攤上這事”醮铮” “怎么了奶稠?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捡遍。 經(jīng)常有香客問我锌订,道長,這世上最難降的妖魔是什么画株? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任辆飘,我火速辦了婚禮,結(jié)果婚禮上谓传,老公的妹妹穿的比我還像新娘蜈项。我一直安慰自己,他們只是感情好续挟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布紧卒。 她就那樣靜靜地躺著,像睡著了一般庸推。 火紅的嫁衣襯著肌膚如雪常侦。 梳的紋絲不亂的頭發(fā)上浇冰,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天贬媒,我揣著相機(jī)與錄音,去河邊找鬼肘习。 笑死际乘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的漂佩。 我是一名探鬼主播脖含,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼罪塔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了养葵?” 一聲冷哼從身側(cè)響起征堪,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎关拒,沒想到半個月后佃蚜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體着绊,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谐算,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了归露。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洲脂。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剧包,靈堂內(nèi)的尸體忽然破棺而出恐锦,到底是詐尸還是另有隱情,我是刑警寧澤疆液,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布踩蔚,位于F島的核電站,受9級特大地震影響枚粘,放射性物質(zhì)發(fā)生泄漏馅闽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一馍迄、第九天 我趴在偏房一處隱蔽的房頂上張望福也。 院中可真熱鬧,春花似錦攀圈、人聲如沸暴凑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽现喳。三九已至,卻和暖如春犬辰,著一層夾襖步出監(jiān)牢的瞬間嗦篱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工幌缝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灸促,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像浴栽,于是被迫代替她去往敵國和親荒叼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 作者:雲(yún)霏霏原文地址:http://www.cnblogs.com/yunfeifei/ 現(xiàn)在最熱門的前端框架有A...
    IT程序獅閱讀 1,553評論 1 38
  • React 入門實(shí)例教程 轉(zhuǎn)載(加入了自己的一些東西典鸡,推薦看原文):一看就懂的ReactJs入門教程(精華版) ...
    驀然之間的閱讀 401評論 0 0
  • 按照慣例被廓,先給ReactJS背書 React是一個Facebook開發(fā)的UI庫,于2013年5月開源萝玷,并迅速的從最...
    艾倫先生閱讀 3,226評論 1 12
  • react簡介 react是由Fecebook開發(fā)的UI庫伊者,它的核心思想開發(fā)reactJS的組件可以重復(fù)調(diào)用,易于...
    小_b6d4閱讀 457評論 0 0
  • 在React這股目前最熱前端框架之風(fēng)刮來之前间护,一直在Cocos2d-html5游戲和半路出家的Android應(yīng)用的...
    hahafei閱讀 365評論 0 2