React基礎(chǔ)——JSX語法

JSX是React的核心組成部分兰粉,它使用XML標(biāo)記的方式去直接聲明界面棚赔,界面組件之間可以互相嵌套单寂∑床裕可以理解為在JS中編寫與XML類似的語言,一種定義帶屬性樹結(jié)構(gòu)(DOM結(jié)構(gòu))的語法笑诅,它的目的不是要在瀏覽器或者引擎中實現(xiàn),它的目的是通過各種編譯器將這些標(biāo)記編譯成標(biāo)準(zhǔn)的JS語言疮鲫。

雖然你可以完全不使用JSX語法吆你,只使用JS語法,但還是推薦使用JSX俊犯,可以定義包含屬性的樹狀結(jié)構(gòu)的語法妇多,類似HTML標(biāo)簽?zāi)菢拥氖褂茫腋阌诖a的閱讀燕侠。

使用JSX語法后者祖,你必須要引入babel的JSX解析器,把JSX轉(zhuǎn)化成JS語法绢彤,這個工作會由babel自動完成七问。同時引入babel后,你就可以使用新的es6語法茫舶,babel會幫你把es6語法轉(zhuǎn)化成es5語法械巡,兼容更多的瀏覽器。

我們從最簡單的一個官網(wǎng)例子helloworld開始:

  <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8" />
      <title>Hello React!</title>
      <script src="vendor-js/react.js"></script>
      <script src="vendor-js/react-dom.js"></script>
      <script src="vendor-js/babel-core/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>

在這個簡單的例子中姆涩,看不出來有任何jsx語法的地方矫废,當(dāng)其中<h1>Hello,world</h1>就是使用到了jsx語法蚪缀。HTML 語言直接寫在 JavaScript 語言之中,不加任何引號古程,這就是 JSX 的語法,它允許 HTML 與 JavaScript 的混寫喊崖。如果轉(zhuǎn)化成純JavaScript 的話挣磨,就是:

    <script type="text/javascript">
      ReactDOM.render(
        React.DOM.h1(null,'hello,world!'),
        document.getElementById('example')
      );
    </script>

在上述JSX語法中有兩個要注意的地方:

  • <script> 標(biāo)簽的 type 屬性為 text/babel,這是React 獨有的 JSX 語法贷祈,跟 JavaScript 不兼容趋急。凡是在頁面中直接使用 JSX 的地方,都要加上 type="text/babel"势誊。
  • 一共用了三個庫: react.js 呜达、react-dom.js 和 browser.min.js ,它們必須首先加載粟耻。其中查近,react.js 是 React 的核心庫眉踱,react-dom.js 是提供與 DOM 相關(guān)的功能, browser.min.js的作用是將 JSX 語法轉(zhuǎn)為 JavaScript 語法霜威。

將 JSX 語法轉(zhuǎn)為 JavaScript 語法谈喳,這一步很消耗時間。現(xiàn)在前端項目戈泼,都會使用前端工程化婿禽,不會直接在html頁面中直接寫js代碼,寫好的js代碼都會使用工具進(jìn)行編譯壓縮等大猛。這樣的話扭倾,我們的jsx也會通過編譯直接轉(zhuǎn)化成js語法,讓瀏覽器直接使用挽绩。

ReactDOM.render 是 React 的最基本方法膛壹,將模板轉(zhuǎn)為HTML語言,并插入指定的 DOM 節(jié)點唉堪。

JSX的特點:

  1. 類XML語法容易接受模聋,結(jié)構(gòu)清晰
  2. 增強(qiáng)JS語義
  3. 抽象程度高,屏蔽DOM操作唠亚,跨平臺
  4. 代碼模塊化

JSX基本語法規(guī)則:

JSX本身就和XML語法類似链方,可以定義屬性以及子元素。唯一特殊的是可以用大括號來加入JavaScript表達(dá)式趾撵。遇到 HTML 標(biāo)簽(以 < 開頭)侄柔,就用 HTML 規(guī)則解析;遇到代碼塊(以 { 開頭)占调,就用 JavaScript 規(guī)則解析暂题。

var arr = [
 <h1>Hello world!</h1>,
 <h2>React is awesome</h2>,
];
ReactDOM.render(
 <div>{arr}</div>,
 document.getElementById('example')
);

這個就是一個簡單的html與js混用的例子。arr變量中存在html元素究珊,div中又使用了arr這個js變量薪者。轉(zhuǎn)化成純javascript的話:

var h1=React.DOM.h1(null,'Hello world!');
var h2=React.DOM.h1(null,'React is awesome');
var div=React.DOM.div(null,h1,h2);
ReactDOM.render(
 div,
 document.getElementById('example')
);

React組件

我們使用jsx來將代碼封裝成React組件,然后像插入普通 HTML 標(biāo)簽一樣剿涮,在其他地方插入這個組件言津。使用React.createClass用于生成一個組件。

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

上面代碼中取试,變量 MyComponent就是一個組件類悬槽。模板插入 <MyComponent /> 時,會自動生成 MyComponent 的一個實例(下文的"組件"都指組件類的實例)瞬浓。所有組件類都必須有自己的 render 方法初婆,用于輸出組件。

React 可以渲染 HTML 標(biāo)簽 (strings) 或 React 組件 (classes)。

  • 在react中通常約定組件類的第一個字母必須大寫磅叛,html標(biāo)簽都是小寫屑咳。

//要渲染 HTML 標(biāo)簽,只需在 JSX 里使用小寫字母開頭的標(biāo)簽名弊琴。
var myDivElement = <div className="foo" />;
React.render(myDivElement, document.getElementById('example'));
//要渲染 React 組件兆龙,只需創(chuàng)建一個大寫字母開頭的本地變量。
var MyComponent = React.createClass({/.../});
var myElement = <MyComponent />;
React.render(myElement, document.getElementById('example'));

* 還有一個注意點:組件類只能包含一個頂層標(biāo)簽敲董,否則會報錯紫皇。
```javascript

//var myDivElement =<h1>你好</h1><h1>hello</h1>;
//上述寫法是會報錯的,要寫成只有一個頂層標(biāo)簽:
var myDivElement =<div><h1>你好</h1><h1>hello</h1></div>;

上述代碼一個靜態(tài)的組件臣缀,下面看一個動態(tài)組件:

var MyComponent=React.createClass({
  getInitialState: function() {
       return {clickNum: 0};
  },
  handleClick:function(){
    var num=this.state.clickNum;
    num++;
    this.setState({clickNum:num});
  },
  render: function() {
   return (
      <div>
        <h1 onClick={this.handleClick}>Hello {this.props.name}!</h1>
        <h2 style={{color:'red'}}>點擊{this.props.name}次數(shù):{this.state.clickNum}</h2>
      </div>
    );
 }
});
ReactDOM.render(
  <div>
     <MyComponent name="張三" />
     <hr/>
     <MyComponent name="李四" />
  </div>,
 document.getElementById('example')
);

上面代碼中定義的MyComponent組件包含屬性坝橡,狀態(tài)和事件泻帮,是一個簡單的比較完整的組件精置。使用props通過父組件進(jìn)行傳遞值,使用state定義組件自己的狀態(tài)锣杂,組件支持的大部分的DOM操作事件脂倦。

關(guān)于屬性props:

  • class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor 元莫,這是因為 class 和 for 是 JavaScript 的保留字赖阻。
  • 直接在標(biāo)簽上使用style屬性時,要寫成style={{}}是兩個大括號踱蠢,外層大括號是告知jsx這里是js語法火欧,和真實DOM不同的是,屬性值不能是字符串而必須為對象茎截,需要注意的是屬性名同樣需要駝峰命名法苇侵。即margin-top要寫成marginTop。
  • this.props.children 不要children作為把對象的屬性名企锌。因為this.props.children獲取的該標(biāo)簽下的所有子標(biāo)簽榆浓。this.props.children 的值有三種可能:如果當(dāng)前組件沒有子節(jié)點,它就是 undefined ;如果有一個子節(jié)點撕攒,數(shù)據(jù)類型是 object 陡鹃;如果有多個子節(jié)點,數(shù)據(jù)類型就是 array 抖坪。所以萍鲸,處理 this.props.children 的時候要小心。官方建議使用React.Children.map來遍歷子節(jié)點擦俐,而不用擔(dān)心數(shù)據(jù)類型脊阴。

關(guān)于狀態(tài)state:

  • 組件免不了要與用戶互動,React 將組件看成是一個狀態(tài)機(jī),一開始有一個初始狀態(tài)蹬叭,然后用戶互動藕咏,導(dǎo)致狀態(tài)變化,從而觸發(fā)重新渲染 UI秽五。
  • getInitialState 方法用于定義初始狀態(tài)孽查,也就是一個對象,這個對象可以通過 this.state 屬性讀取坦喘。當(dāng)用戶點擊組件盲再,導(dǎo)致狀態(tài)變化,this.setState 方法就修改狀態(tài)值瓣铣,每次修改以后答朋,自動調(diào)用 this.render 方法,再次渲染組件棠笑。

由于 this.props 和 this.state 都用于描述組件的特性梦碗,可能會產(chǎn)生混淆。一個簡單的區(qū)分方法是蓖救,this.props 表示那些一旦定義洪规,就不再改變的特性,而 this.state 是會隨著用戶互動而產(chǎn)生變化的特性循捺。

注意點:
如果往原生 HTML 元素里傳入 HTML 規(guī)范里不存在的屬性斩例,React 不會顯示它們。如果需要使用自定義屬性从橘,要加 data- 前綴念赶。

<div data-custom-attribute="foo" />

PropTypes

組件的屬性props可以接受任意值,字符串恰力、對象叉谜、函數(shù)等等都可以。有時牺勾,我們需要一種機(jī)制正罢,驗證別人使用組件時,提供的參數(shù)是否符合要求驻民。React中使用PropTypes進(jìn)行參數(shù)的校驗翻具。

var MyTitle = React.createClass({
   propTypes: {
     title: React.PropTypes.string.isRequired,
   },
   render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

上面的Mytitle組件有一個title屬性。PropTypes 告訴 React回还,這個 title 屬性是必須的裆泳,而且它的值必須是字符串。當(dāng)我們給title傳遞一個數(shù)字時柠硕,控制臺就會報錯:

Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.

此外工禾,getDefaultProps 方法可以用來設(shè)置組件屬性的默認(rèn)值运提。

獲取真實的DOM節(jié)點

組件并不是真實的 DOM 節(jié)點,而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu)闻葵,叫做虛擬 DOM (virtual DOM)民泵。只有當(dāng)它插入文檔以后,才會變成真實的 DOM 槽畔。
有時需要從組件獲取真實 DOM 的節(jié)點栈妆,這時就要用到 ref 屬性。

var MyComponent = React.createClass({
   handleClick: function() {
     this.refs.myTextInput.focus();
   },
   render: function() {
     return (
     <div>
       <input type="text" ref="myTextInput" />
       <input type="button" value="Focus the text input" onClick={this.handleClick} />
     </div>
     );
   }
});

為了獲取真是DOM節(jié)點厢钧,html元素必須有一個 ref 屬性鳞尔,然后 this.refs.[refName] 就會返回這個真實的 DOM 節(jié)點。需要注意的是早直,由于 this.refs.[refName] 屬性獲取的是真實 DOM 寥假,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性霞扬,否則會報錯糕韧。

求值表達(dá)式

要使用 JavaScript 表達(dá)式作為屬性值,只需把這個表達(dá)式用一對大括號 ( { } ) 包起來祥得,不要用引號 ( " " )兔沃。
在編寫JSX時,在 { } 中不能使用語句(if語句级及、for語句等等),但可以使用求值表達(dá)式额衙,這本身與JSX沒有多大關(guān)系饮焦,是JS中的特性,它是會返回值的表達(dá)式窍侧。我們不能直接使用語句县踢,但可以把語句包裹在函數(shù)求值表達(dá)式中運用。

條件判斷的寫法

你沒法在JSX中使用 if-else 語句伟件,因為 JSX 只是函數(shù)調(diào)用和對象創(chuàng)建的語法糖硼啤。在 { } 中使用,是不合法的JS代碼斧账,不過可以采用三元操作表達(dá)式

var HelloMessage = React.createClass({ 
  render: function() { 
    return <div>Hello {this.props.name 谴返? this.props.name : "World"}</div>; 
  }
});
ReactDOM.render(<HelloMessage name="xiaowang" />, document.body);

可以使用比較運算符“ || ”來書寫,如果左邊的值為真咧织,則直接返回左邊的值嗓袱,否則返回右邊的值,與if的效果相同习绢。

var HelloMessage = React.createClass({ 
  render: function() { 
    return <div>Hello {this.props.name || "World"}</div>; 
  }
});
函數(shù)表達(dá)式

( )有強(qiáng)制運算的作用

var HelloMessage = React.createClass({ 
  render: function() { 
    return <div>Hello { 
    (function(obj){ 
        if(obj.props.name) 
          return obj.props.name 
        else 
          return "World" 
      }(this)) 
    }</div>; 
  }
});
ReactDOM.render(<HelloMessage name="xiaowang" />, document.body);

外括號“ )”放在外面和里面都可以執(zhí)行渠抹。唯一的區(qū)別是括號放里面執(zhí)行完畢拿到的是函數(shù)的引用蝙昙,然后再調(diào)用“function(){}(this)()”;括號放在外面的時候拿到的事返回值梧却。

組件的生命周期

組件的生命周期分成三個狀態(tài):

* Mounting:已插入真實 DOM
* Updating:正在被重新渲染
* Unmounting:已移出真實 DOM

React 為每個狀態(tài)都提供了兩種處理函數(shù)奇颠,will 函數(shù)在進(jìn)入狀態(tài)之前調(diào)用,did 函數(shù)在進(jìn)入狀態(tài)之后調(diào)用放航,三種狀態(tài)共計五種處理函數(shù)大刊。

* componentWillMount()
* componentDidMount()
* componentWillUpdate(object nextProps, object nextState)
* componentDidUpdate(object prevProps, object prevState)
* componentWillUnmount()

此外,React 還提供兩種特殊狀態(tài)的處理函數(shù)三椿。

* componentWillReceiveProps(object nextProps):已加載組件收到新的參數(shù)時調(diào)用
* shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時調(diào)用

注釋

JSX 里添加注釋很容易缺菌;它們只是 JS 表達(dá)式而已。你只需要在一個標(biāo)簽的子節(jié)點內(nèi)(非最外層)小心地用 {} 包圍要注釋的部分搜锰。

{/* 一般注釋, 用 {} 包圍 */}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伴郁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蛋叼,更是在濱河造成了極大的恐慌焊傅,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狈涮,死亡現(xiàn)場離奇詭異狐胎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)歌馍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門握巢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人松却,你說我怎么就攤上這事暴浦。” “怎么了晓锻?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵歌焦,是天一觀的道長。 經(jīng)常有香客問我砚哆,道長独撇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任躁锁,我火速辦了婚禮纷铣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灿里。我一直安慰自己关炼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布匣吊。 她就那樣靜靜地躺著儒拂,像睡著了一般寸潦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上社痛,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天见转,我揣著相機(jī)與錄音,去河邊找鬼蒜哀。 笑死斩箫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撵儿。 我是一名探鬼主播乘客,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淀歇!你這毒婦竟也來了易核?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤浪默,失蹤者是張志新(化名)和其女友劉穎牡直,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纳决,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡碰逸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阔加。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饵史。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖掸哑,靈堂內(nèi)的尸體忽然破棺而出约急,到底是詐尸還是另有隱情,我是刑警寧澤苗分,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站牵辣,受9級特大地震影響摔癣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纬向,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一择浊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逾条,春花似錦琢岩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽江锨。三九已至,卻和暖如春糕篇,著一層夾襖步出監(jiān)牢的瞬間啄育,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工拌消, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留挑豌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓墩崩,卻偏偏與公主長得像氓英,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鹦筹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

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

  • 40铝阐、React 什么是React?React 是一個用于構(gòu)建用戶界面的框架(采用的是MVC模式):集中處理VIE...
    萌妹撒閱讀 1,017評論 0 1
  • React簡介 (1)簡介 React 起源于 Facebook 的內(nèi)部項目盛龄,因為該公司對市場上所有 JavaSc...
    魚魚吃貓貓閱讀 1,628評論 1 6
  • 1饰迹、什么是react React.js 是一個幫助你構(gòu)建頁面 UI 的庫。React.js 將幫助我們將界面分成了...
    谷子多閱讀 2,557評論 1 13
  • HTML模版 之后出現(xiàn)的React代碼嵌套入模版中余舶。 1. Hello world 這段代碼將一個一級標(biāo)題插入到指...
    ryanho84閱讀 6,238評論 0 9
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南啊鸭,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出匿值,比目前大...
    leonaxiong閱讀 2,838評論 1 18