react入門教程一

react簡(jiǎn)介

React 起源于 Facebook 的內(nèi)部項(xiàng)目狗超,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套恕曲,用來(lái)架設(shè)Instagram 的網(wǎng)站切心。做出來(lái)以后飒筑,發(fā)現(xiàn)這套東西很好用,就在2013年5月開源了绽昏。

由于 React的設(shè)計(jì)思想極其獨(dú)特协屡,屬于革命性創(chuàng)新,性能出眾全谤,代碼邏輯卻非常簡(jiǎn)單肤晓。所以,越來(lái)越多的人開始關(guān)注和使用认然,認(rèn)為它可能是將來(lái) Web 開發(fā)的主流工具补憾。

這個(gè)項(xiàng)目本身也越滾越大,從最早的UI引擎變成了一整套前后端通吃的 Web App 解決方案季眷。衍生的 React Native 項(xiàng)目余蟹,目標(biāo)更是宏偉,希望用寫 Web App 的方式去寫 Native App子刮。如果能夠?qū)崿F(xiàn)威酒,整個(gè)互聯(lián)網(wǎng)行業(yè)都會(huì)被顛覆,因?yàn)橥唤M人只需要寫一次 UI 挺峡,就能同時(shí)運(yùn)行在服務(wù)器葵孤、瀏覽器和手機(jī)。

特點(diǎn):

  1. 聲明式設(shè)計(jì):React采用聲明范式橱赠,可以輕松描述應(yīng)用尤仍。
  2. 高效:React通過(guò)對(duì)DOM的模擬,最大限度地減少與DOM的交互狭姨。
  3. 靈活:React可以與已知的庫(kù)或框架很好地配合宰啦。

一些好的學(xué)習(xí)途徑:

阮一峰-React 技術(shù)棧系列教程

react中文社區(qū)

官方文檔

react入門知識(shí)儲(chǔ)備

ES6

react推薦使用ES6語(yǔ)法,如果你已經(jīng)熟悉ES6饼拍,那就最好去使用ES6赡模。

但如果你并不很了解,使用之前的ES語(yǔ)法也是可以的师抄,但在此之前漓柑,你一定要先了解ES6的 const,let 以及 箭頭函數(shù)。

Webpack & Babel

Babel用于將ES6及jsx語(yǔ)法翻譯成瀏覽器可以識(shí)別渲染的語(yǔ)法辆布,而Webpack則用于將這一過(guò)程自動(dòng)化瞬矩,從而提高開發(fā)效率。

前期學(xué)習(xí)過(guò)程中可以借助腳手架去配置Webpack和Babel锋玲,但是要試著去看懂理解他們的配置景用,逐漸去擺脫腳手架的束縛。

react兩種前端使用方法

直接使用

通過(guò)script標(biāo)簽引入

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.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>

注意:

  1. 最后一個(gè) <script>標(biāo)簽的 type 屬性為 text/babel 嫩絮。這是因?yàn)?React 獨(dú)有的 JSX 語(yǔ)法丛肢,跟 JavaScript 不兼容。凡是使用 JSX 的地方剿干,都要加上 type="text/babel" 蜂怎。
  2. 上面代碼一共用了三個(gè)庫(kù): react.js 、react-dom.js 和 Browser.js 置尔,它們必須首先加載杠步。

webpack打包編譯

安裝node環(huán)境,使用npm安裝依賴榜轿,創(chuàng)建項(xiàng)目幽歼,配置webpack,babel谬盐。甸私。。

這里不再贅述飞傀,不會(huì)的可以參考這篇博文webpack入門+react環(huán)境配置

每次開發(fā)都要去配置太麻煩了皇型,熟悉webpack之后我們可以使用腳手架快速搭建開發(fā)環(huán)境

關(guān)于react腳手架的匯總和使用可以參考我的另一篇博文快速構(gòu)建React+Webpack+ES6項(xiàng)目

JSX語(yǔ)法及組件

JSX

React 使用 JSX 來(lái)替代常規(guī)的 JavaScript。

JSX 的基本語(yǔ)法規(guī)則:遇到 HTML 標(biāo)簽(以 < 開頭)砸烦,就用 HTML 規(guī)則解析弃鸦;遇到代碼塊(以 { 開頭),就用 JavaScript 規(guī)則解析幢痘。

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example'),
  function () {
    console.log('渲染結(jié)束回調(diào)函數(shù)在這里!')
  }
);

JSX語(yǔ)法具備以下特點(diǎn):

  1. 可以在 JSX 中使用 JavaScript 表達(dá)式唬格。表達(dá)式寫在花括號(hào) {} 中。
  2. 在 JSX 中不能使用 if else 語(yǔ)句颜说,但可以使用 conditional (三元運(yùn)算) 表達(dá)式來(lái)替代购岗,這一點(diǎn)官方文檔有詳細(xì)說(shuō)明。
  3. React 推薦使用內(nèi)聯(lián)樣式门粪,但是這里內(nèi)聯(lián)樣式作為對(duì)象的形勢(shì)藕畔,使用{}包裹起來(lái)。
  4. JSX 允許直接在模板插入 JavaScript 變量庄拇。如果這個(gè)變量是一個(gè)數(shù)組,則會(huì)展開這個(gè)數(shù)組的所有成員(數(shù)組中的每一項(xiàng)元素都需要添加一個(gè)key屬性)。
  5. JSX的注釋使用/* ... */寫在{}中措近。

tip:在jsx中給標(biāo)簽添加屬性需要注意溶弟, class 屬性需要寫成 classNamefor 屬性需要寫成 htmlFor 瞭郑,這是因?yàn)?classfor 是 JavaScript 的保留字辜御。

具體效果我們將在后面演示的代碼中體現(xiàn)。

組件

React 允許將代碼封裝成組件(component)屈张,然后像插入普通 HTML 標(biāo)簽一樣擒权,在網(wǎng)頁(yè)中插入這個(gè)組件,官方是這么說(shuō)的阁谆。但是實(shí)際上我們實(shí)際的業(yè)務(wù)代碼基本都是一個(gè)又一個(gè)的組件堆砌而成碳抄,這樣做有很多好處。首先得益于react的局部刷新场绿,每次更新頁(yè)面內(nèi)容時(shí)我們只需操作和更新對(duì)應(yīng)的組件即可剖效,無(wú)需對(duì)整個(gè)頁(yè)面進(jìn)行重新渲染。組件使頁(yè)面模塊化焰盗,結(jié)構(gòu)更加清晰璧尸。此外組件提高了代碼的復(fù)用率,提高編碼效率......

react使用React.createClass 方法生成一個(gè)組件類熬拒。

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello World!</h1>
  }
});
 
ReactDOM.render(
  <HelloMessage />,
  document.getElementById('example')
);

上面就是一個(gè)簡(jiǎn)單的HelloMessage組件爷光,這里需要注意:

  1. 組件類的第一個(gè)字母必須大寫,jsx使用標(biāo)簽首字母的大小寫來(lái)區(qū)分原生標(biāo)簽和組件澎粟,上面代碼中的HelloMessage組件如果命名為helloMessage蛀序,ReactDOM在渲染時(shí)會(huì)認(rèn)為這是一個(gè)HTML原生標(biāo)簽,從而導(dǎo)致渲染失敗捌议。
  2. 組件類只能包含一個(gè)頂層標(biāo)簽 哼拔,這個(gè)意思就是每一個(gè)組件必須要包裹在一個(gè)標(biāo)簽內(nèi),如果上面的代碼寫成return (<h1>Hello World!</h1><h2>Hello React!</h2>) 瓣颅,即一個(gè)組件內(nèi)存在兩個(gè)頂層標(biāo)簽倦逐,這樣是不被允許的。

組件允許嵌套宫补,即一個(gè)組件內(nèi)嵌套另一個(gè)組件:

var HelloMessage = React.createClass({
  render: function() {
    return (
      <div>
        <h1>Hello World!</h1>
        <MessageBox/>
      </div>
    )
  }
});

var MessageBox = React.createClass({
  render: function() {
    return <h3>Hello React!</h3>
  }
})
 
ReactDOM.render(
  <HelloMessage />,
  document.getElementById('example')
);

上面代碼我們可以看到我們創(chuàng)建了一個(gè)新的組件MessageBox檬姥,并把它放在了HelloMeaasge組件中。同時(shí)大家也會(huì)注意到粉怕,我在HelloMessage的return中放了一個(gè)div包裹整個(gè)組件內(nèi)容健民,這也是上面提到的組件只能有一個(gè)頂層標(biāo)簽的原因。另外標(biāo)簽一定注意閉合贫贝,包括組件標(biāo)簽秉犹,不然會(huì)報(bào)錯(cuò)不能正常渲染蛉谜。瀏覽器中運(yùn)行如下:

1

上面說(shuō)到JSX的時(shí)候我提到了jsx可以自動(dòng)展開數(shù)組,這里我們來(lái)試一下:

var HelloMessage = React.createClass({
  render: function() {
    var arr= [];
    for (var i = 0; i < 5; i++) {
      arr.push(<MessageBox key={i}/>)
    }
    
    return (
      <div>
        <h1>Hello World!</h1>
        {arr}
      </div>
    )
  }
});

var MessageBox = React.createClass({
  render: function() {
    return <h3>Hello React!</h3>
  }
})
 
ReactDOM.render(
  <HelloMessage />,
  document.getElementById('example')
);

這里我們創(chuàng)建一個(gè)數(shù)組崇堵,使用for循環(huán)把組件MessageBox循環(huán)五遍放進(jìn)數(shù)組中型诚,而在HelloMessage組件中我們僅僅使用花括號(hào)來(lái)包裹數(shù)組,react在解析時(shí)就會(huì)把這個(gè)arr作為js變量來(lái)解析鸳劳,發(fā)現(xiàn)它是數(shù)組就直接展開數(shù)組內(nèi)容狰贯。運(yùn)行結(jié)果如下:

2

具體組件中的數(shù)據(jù)傳遞,我們將在下節(jié)中講到赏廓。

react數(shù)據(jù)載體

react中的數(shù)據(jù)載體有三個(gè):state涵紊,props 和 context。他們?cè)趓eact起著重要的作用幔摸。

State

React 里主要使用state來(lái)定義組件內(nèi)部狀態(tài)摸柄。

在頁(yè)面中我們只需更新組件的 state,然后用戶界面就會(huì)根據(jù)我們的設(shè)定重新渲染抚太。

來(lái)看下面的例子:

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'haven\'t liked';
    return (
      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </p>
    );
  }
});

ReactDOM.render(
  <LikeButton />,
  document.getElementById('example')
);

這段代碼中我們首先定義了一個(gè)LikeButton組件塘幅,使用getInitialState方法定義初始狀態(tài),即一個(gè)對(duì)象尿贫,對(duì)象中的值可以通過(guò)this.state.liked獲取电媳。然后我們給p標(biāo)簽綁定一個(gè)點(diǎn)擊事件handleClick,當(dāng)用戶點(diǎn)擊時(shí)通過(guò)this.setState方法去改變liked的值庆亡。當(dāng)react發(fā)現(xiàn)state的值發(fā)生改變匾乓,就會(huì)重新調(diào)用this.render方法重新渲染組件。細(xì)心的同學(xué)可能會(huì)注意到j(luò)sx中不能使用if又谋,所以這里使用了三元運(yùn)算符來(lái)改變text的值拼缝。

我們可以通過(guò)定義一個(gè)變量來(lái)獲取render:

var likeButton= ReactDOM.render(
  <LikeButton />,
  document.getElementById('example')
);
3

在控制臺(tái)中你會(huì)看到render返回的一個(gè)對(duì)象,里面包括了context彰亥,props咧七,state這些值以及handleClick這樣的事件等。這里可以看到state是一個(gè)對(duì)象任斋,如果我們直接去改變這個(gè)state继阻,雖然可以成功改變,但是你會(huì)發(fā)現(xiàn)頁(yè)面沒(méi)有任何變化:

4

在react中废酷,state方法主要用于數(shù)據(jù)的調(diào)用瘟檩,此時(shí)雖然數(shù)據(jù)更改了但是不會(huì)自動(dòng)的使頁(yè)面得到更新,而官方則給出了forceUpdate()方法去手動(dòng)更新頁(yè)面澈蟆。所以在實(shí)際的項(xiàng)目中可以根據(jù)需求來(lái)決定使用setState來(lái)自動(dòng)更新頁(yè)面墨辛,還是使用state+forceUpdate。

Props & Context

props和context比較相似趴俘,是用于組件之間通信睹簇,不同的是props只能逐層傳遞奏赘,但是content可以跨組件傳遞。

雖然context很強(qiáng)大带膀,但是React官方文檔卻不推薦使用志珍,首先props可以讓你看到哪些數(shù)據(jù)在傳遞,可以使代碼更易讀垛叨,context則不然;其次context是react一個(gè)實(shí)驗(yàn)性API柜某,有可能在未來(lái)的版本中移除嗽元。

在一般的項(xiàng)目中,簡(jiǎn)單的數(shù)據(jù)傳遞一般使用props喂击,而復(fù)雜狀態(tài)則使用Redux 或MobX狀態(tài)管理庫(kù)剂癌。

所以這里著重來(lái)說(shuō)一下props,而對(duì)context感興趣的童鞋可以去看這篇博客:React 中 context 的使用

首先來(lái)寫一個(gè)簡(jiǎn)單的demo:

var Button = React.createClass({
  render: function() {
    return (
      <button style={{background: this.props.color}}>刪除</button>
    );
  }
});

var Message= React.createClass({
    render: function() {
        var test = [];
        var color = this.props.color;
        this.props.text.forEach(function(msg,index){
            test.push(<p key={index}>{msg}<Button color={color}/></p>)
        });
        
        return (
            <div>{test}</div>
        )
    }
})

var message = ReactDOM.render(
  <Message text={["這是一段文字","這是另一段文字"]} color={"red"}/>,
  document.getElementById('example')
);

這段代碼首先創(chuàng)建一個(gè)Button組件翰绊,按鈕的顏色定義為props佩谷。然后Button被嵌套進(jìn)Message組件中。實(shí)際渲染時(shí)我們?cè)?<Mesaage/> 中定義text和color的值监嗜,Message組件接收并將color傳遞給Button組件谐檀,同時(shí)使用forEach循環(huán)text數(shù)組。但是如果傳來(lái)的text不是一個(gè)數(shù)組裁奇,那么forEach肯定會(huì)報(bào)錯(cuò)桐猬,這里就需要用到props的數(shù)據(jù)驗(yàn)證:

var Message= React.createClass({
    propTypes: {
        text: React.PropTypes.array,
    },
    getDefaultProps:function() {
        return {
            text: ["默認(rèn)的消息"]
        }
    },
    render: function() {
        var test = [];
        var color = this.props.color;
        this.props.text.forEach(function(msg,index){
            test.push(<p key={index}>{msg}<Button color={color}/></p>)
        });
        
        return (
            <div>{test}</div>
        )
    }
})

這里給Message組件加了兩個(gè)一個(gè)propTypes用于驗(yàn)證props的值類型,也可以在array后加.isRequire規(guī)定text值不能為空刽肠。以及getDefaultProps用于定義props的默認(rèn)值溃肪。但是這里注意一點(diǎn),出于性能原因音五,propTypes僅在開發(fā)模式下檢查惫撰。更多propTypes的驗(yàn)證類型參考官網(wǎng)文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末躺涝,一起剝皮案震驚了整個(gè)濱河市厨钻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诞挨,老刑警劉巖莉撇,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異惶傻,居然都是意外死亡棍郎,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門银室,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涂佃,“玉大人励翼,你說(shuō)我怎么就攤上這事」架” “怎么了汽抚?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)伯病。 經(jīng)常有香客問(wèn)我造烁,道長(zhǎng),這世上最難降的妖魔是什么午笛? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任惭蟋,我火速辦了婚禮,結(jié)果婚禮上药磺,老公的妹妹穿的比我還像新娘告组。我一直安慰自己,他們只是感情好癌佩,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布木缝。 她就那樣靜靜地躺著,像睡著了一般围辙。 火紅的嫁衣襯著肌膚如雪我碟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天酌畜,我揣著相機(jī)與錄音怎囚,去河邊找鬼。 笑死桥胞,一個(gè)胖子當(dāng)著我的面吹牛恳守,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贩虾,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼催烘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了缎罢?” 一聲冷哼從身側(cè)響起伊群,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤结笨,失蹤者是張志新(化名)和其女友劉穎许饿,沒(méi)想到半個(gè)月后腰耙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芜飘,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年诽嘉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挺举。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捐名。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡询刹,死狀恐怖谜嫉,靈堂內(nèi)的尸體忽然破棺而出萎坷,到底是詐尸還是另有隱情,我是刑警寧澤沐兰,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布哆档,位于F島的核電站,受9級(jí)特大地震影響住闯,放射性物質(zhì)發(fā)生泄漏瓜浸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一比原、第九天 我趴在偏房一處隱蔽的房頂上張望斟叼。 院中可真熱鬧,春花似錦春寿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至兄一,卻和暖如春厘线,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背出革。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工造壮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骂束。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓耳璧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親展箱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旨枯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

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

  • 框架優(yōu)點(diǎn): 1.方便開發(fā)、快速寫功能2.統(tǒng)一開發(fā)方式3.調(diào)試混驰、測(cè)試方便 前端三大框架: Angular.js-前端...
    虛幻的銹色閱讀 45,472評(píng)論 1 19
  • 本筆記基于React官方文檔攀隔,當(dāng)前React版本號(hào)為15.4.0。 1. 安裝 1.1 嘗試 開始之前可以先去co...
    Awey閱讀 7,726評(píng)論 14 128
  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,075評(píng)論 2 35
  • 最近看了一本關(guān)于學(xué)習(xí)方法論的書栖榨,強(qiáng)調(diào)了記筆記和堅(jiān)持的重要性昆汹。這幾天也剛好在學(xué)習(xí)React,所以我打算每天堅(jiān)持一篇R...
    gaoer1938閱讀 1,690評(píng)論 0 5
  • It's a common pattern in React to wrap a component in an ...
    jplyue閱讀 3,277評(píng)論 0 2