react系列--基本語法結構

對于剛入門的同學,不建議直接用構建工具搭建項目,先從本地引入開始

1.頁面引入文件

結構大致如下

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="text/babel">
      // ** Our code goes here! **
    </script>
  </body>
</html>

其中需要注意,書寫react語法的script標簽的type屬性為text/babel。因為要使用jsx語法,關于jsx,大家可以點擊react系列--jsx
面代碼一共用了三個庫: react.jsreact-dom.jsBrowser.js ,它們必須首先加載。其中,react.js 是 React 的核心庫,react-dom.js 是提供與 DOM 相關的功能,Browser.js 的作用是將 JSX 語法轉為 JavaScript 語法,這一步很消耗時間,實際上線的時候,應該將它放到服務器完成(babel模塊)。

2.ReactDOM.render()

ReactDOM.render 是 React 的最基本方法,用于將模板轉為 HTML 語言,并插入指定的 DOM 節點。

ReactDOM.render(
 <h1>Hello, world!</h1>,
 document.getElementById('example')
);

上面代碼將一個 h1 標題,插入 example 節點

注意:模板必須唯一頂層元素

3.樣式設置

  • style
ReactDOM.render(
    <div style={{color:'red'}}>
        xxxxx
    </div>,
    document.body
);
  • 類名(className)
ReactDOM.render(
    <div className="box">content</div>,
    document.body
);

4.事件綁定

function say(){
        alert("How old are you?")
}
React.render(
    <button onClick={say} />,
    document.body
);

注意:事件駝峰命名!

5.組件

React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標簽一樣,在網頁中插入這個組件。React.createClass 方法就用于生成一個組件類

var Hello = React.createClass({
  render: function() {
    return <h1>Hello</h1>;
  }
});

ReactDOM.render(
  <Hello />,
  document.getElementById('app')
);

注意:組件模板必須唯一頂層元素

小插曲(HTML 標簽 vs. React 組件)

ReactDOM.render方法可以渲染HTML結構,也可以渲染React組件。
渲染HTML標簽,聲明變量采用首字母

var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.body);

渲染React組件,聲明變量采用首字母

var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.body);

5.1 組件props

注意:react中props與vue不同,只是作為屬性傳遞,是不可變的
this.props 對象的屬性與組件的屬性一一對應

var Hello = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});

ReactDOM.render(
  <Hello  name="veblen"/>,
  document.getElementById('app')
);

但是有一個例外,就是 this.props.children 屬性。它表示組件的所有子節點

var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        this.props.children.map( function (child) {
          return <li>{child}</li>;
        })
      }
      </ol>
    );
  }
});

ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);

這里需要注意,this.props.children 的值有三種可能:如果當前組件沒有子節點,它就是 undefined ;如果有一個子節點,數據類型是object ;如果有多個子節點,數據類型就是 array 。所以,處理 this.props.children 的時候要小心。
React 提供一個工具方法 React.Children 來處理 this.props.children 。我們可以用 React.Children.map來遍歷子點而不用擔心 this.props.children 的數據類型是 undefined還是 object。更多的 React.Children的方法,請參考官方文檔

React.Children.map(this.props.children, function (child) {
          return <li>{child}</li>;
    })

5.2組件PropTypes

組件的屬性可以接受任意值,字符串、對象、函數等等都可以。有時,我們需要一種機制,驗證別人使用組件時,提供的參數是否符合要求。
組件類的PropTypes屬性,就是用來驗證組件實例的屬性是否符合要求

var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

上面的Mytitle組件有一個title屬性。PropTypes 告訴 React,這個 title屬性是必須的,而且它的值必須是字符串。

如果驗證不通過,則會在控制帶顯示錯誤信息!

getDefaultProps方法可以用來設置組件屬性的默認值。

var MyTitle = React.createClass({
  getDefaultProps : function () {
    return {
      title : 'Hello World'
    };
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

ReactDOM.render(
  <MyTitle />,
  document.body
);

上面代碼會輸出"Hello World"。


5.3組件內部事件

var Mybtn=React.createClass({
          say:function(){
                alert("How old are you!")
          }
          render:function(){
                    return(
                          <button onClick={this.say} />
                    )
          }
})

this指向組件實例


5.4組件state

組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然后用戶互動,導致狀態變化,從而觸發重新渲染 UI

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked:true};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  render: function() {
    var text = this.state.liked ? 'love' : 'hate';
    return (
      <p onClick={this.handleClick}>
            I{text}veblen 
      </p>
    );
  }
});

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

上面代碼是一個LikeButton 組件,它的getInitialState 方法用于定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以后,自動調用this.render 方法,再次渲染組件。
由于 this.propsthis.state 都用于描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而this.state 是會隨著用戶互動而產生變化的特性。


5.5組件數據雙向綁定(后期會寫一篇針對數據綁定的文章)

var Input = 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(<Input/>, document.body);

5.6組件生命周期

- componentWillMount()----------掛載前

- componentDidMount()-----------掛載后

- componentWillUpdate(object nextProps, object nextState)-----更新前

- componentDidUpdate(object prevProps, object prevState)-----更新后

- componentWillUnmount()-------銷毀前


6.操作真實DOM

組件并不是真實的 DOM 節點,而是存在于內存之中的一種數據結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文檔以后,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然后再將實際發生變動的部分,反映在真實 DOM上,這種算法叫做 DOM diff ,它可以極大提高網頁的性能表現。但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到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>
    );
  }
});

ReactDOM.render(
  <MyComponent />,
  document.getElementById('app')
);

上面代碼中,組件MyComponent 的子節點有一個文本輸入框,用于獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。為了做到這一點,文本輸入框必須有一個 ref 屬性,然后 this.refs.[refName]就會返回這個真實的 DOM 節點。
需要注意的是,由于 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件之后,才會讀取this.refs.[refName]屬性。


7.獲取數據

組件的數據來源,通常是通過 Ajax 請求從服務器獲取,可以使用 componentDidMount方法(掛載后)設置 Ajax 請求,等到請求成功,再用 this.setState 方法重新渲染 UI


至此,react基本語法結構已介紹完畢,并插入了開發過程中容易出現的問題,加油吧,同學們!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容