React進階(三)

React 起源于 Facebook 的內(nèi)部項目朵夏,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意兰珍,就決定自己寫一套侍郭,用來架設(shè) Instagram 的網(wǎng)站。做出來以后掠河,發(fā)現(xiàn)這套東西很好用亮元,就在2013年5月開源了。


由于 React 的設(shè)計思想極其獨特唠摹,屬于革命性創(chuàng)新爆捞,性能出眾,代碼邏輯卻非常簡單勾拉。所以煮甥,越來越多的人開始關(guān)注和使用,認為它可能是將來 Web 開發(fā)的主流工具藕赞。

一成肘、獲取真實的DOM節(jié)點

組件并不是真實的 DOM 節(jié)點,而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu)斧蜕,叫做虛擬 DOM (virtual DOM)双霍。只有當它插入文檔以后,才會變成真實的 DOM 。根據(jù) React 的設(shè)計洒闸,所有的 DOM 變動染坯,都先在虛擬 DOM 上發(fā)生,然后再將實際發(fā)生變動的部分丘逸,反映在真實 DOM上单鹿,這種算法叫做 DOM diff ,它可以極大提高網(wǎng)頁的性能表現(xiàn)深纲。但是仲锄,有時需要從組件獲取真實 DOM 的節(jié)點,這時就要用到 ref屬性囤萤。示例代碼如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <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">
var MyComponent = React.createClass({
  handleClick: function() {
    this.refs.myTextInput.focus();
  },
  render: function() {
    return (
      <div>
        <input type="text" ref="myTextInput" />
        <input type="button" value="請輸入" onClick={this.handleClick} />
      </div>
    );
  }
});
ReactDOM.render(
  <MyComponent />,
  document.getElementById('example')
);
    </script>
  </body>
</html>

代碼運行結(jié)果如下:

運行結(jié)果顯示

部分代碼如下:

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('example')
);

上面代碼中昼窗,組件 MyComponent 的子節(jié)點有一個文本輸入框是趴,用于獲取用戶的輸入涛舍。這時就必須獲取真實的 DOM 節(jié)點,虛擬 DOM 是拿不到用戶輸入的唆途。為了做到這一點富雅,文本輸入框必須有一個ref屬性,然后 this.refs.[refName]就會返回這個真實的 DOM 節(jié)點肛搬。

需要注意的是没佑,由于 this.refs.[refName]屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后温赔,才能使用這個屬性蛤奢,否則會報錯。上面代碼中陶贼,通過為組件指定 Click 事件的回調(diào)函數(shù)啤贩,確保了只有等到真實 DOM 發(fā)生 Click 事件之后,才會讀取 this.refs.[refName]屬性拜秧。

React 組件支持很多事件痹屹,除了 Click事件以外,還有 KeyDown 枉氮、Copy
志衍、Scroll等,完整的事件清單請查看官方文檔聊替。

二楼肪、this.state

組件免不了要與用戶互動,React 的一大創(chuàng)新惹悄,就是將組件看成是一個狀態(tài)機春叫,一開始有一個初始狀態(tài),然后用戶互動,導致狀態(tài)變化象缀,從而觸發(fā)重新渲染 UI 蔬将。示例代碼如下:

<!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="example"></div>
    <script type="text/babel">
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')
);
    </script>
  </body>
</html>

代碼運行結(jié)果如下:

代碼顯示結(jié)果

部分代碼如下:

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')
);

上面代碼是一個 LikeButton 組件,它的 getInitialState 方法用于定義初始狀態(tài)央星,也就是一個對象霞怀,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件莉给,導致狀態(tài)變化毙石,this.setState 方法就修改狀態(tài)值,每次修改以后颓遏,自動調(diào)用 this.render 方法徐矩,再次渲染組件。

由于 this.props 和 this.state 都用于描述組件的特性叁幢,可能會產(chǎn)生混淆滤灯。一個簡單的區(qū)分方法是,this.props 表示那些一旦定義曼玩,就不再改變的特性鳞骤,而 this.state 是會隨著用戶互動而產(chǎn)生變化的特性。

三黍判、表單

用戶在表單填入的內(nèi)容豫尽,屬于用戶跟組件的互動,所以不能用 this.props 讀取顷帖。示例代碼如下:

<!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="example"></div>
    <script type="text/babel">
      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.getElementById('example'));
    </script>
  </body>
</html>

代碼運行結(jié)果如下:

代碼運行顯示

部分代碼如下:

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);

上面代碼中美旧,文本輸入框的值,不能用 this.props.value讀取贬墩,而要定義一個 onChange事件的回調(diào)函數(shù)榴嗅,通過event.target.value讀取用戶輸入的值。textarea元素震糖、select元素录肯、radio元素都屬于這種情況,更多介紹請參考官方文檔吊说。

在碼代碼的過程中碰到不能理解的東西论咏,再去找找這個東西是什么?拿來做什么颁井?覺得理解得差不多了繼續(xù)閱讀學習厅贪。如果覺得理解差不多了就收工,抱著等以后會用到的時候再來深究雅宾,其實這樣并不好养涮。

我們身為碼農(nóng), 就是要一直碼代碼一直碼代碼,但是在碼代碼的過程中想想這個來實現(xiàn)什么功能模塊贯吓,學習下別人的思路(但是也不要丟掉個人的想法盲目的追尋)及寫代碼的規(guī)范等等懈凹。過程雖慢,但是收獲絕對比只看不練多得多(個人理解)悄谐,這是我最近以來親身體會介评。 道理誰都懂……只看愿不愿意花時間在練代碼上了。

加油爬舰!愿生活對努力的人溫柔以待C锹健!情屹!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坪仇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子垃你,更是在濱河造成了極大的恐慌椅文,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜡镶,死亡現(xiàn)場離奇詭異雾袱,居然都是意外死亡恤筛,警方通過查閱死者的電腦和手機官还,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毒坛,“玉大人望伦,你說我怎么就攤上這事〖逡螅” “怎么了屯伞?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長豪直。 經(jīng)常有香客問我劣摇,道長,這世上最難降的妖魔是什么弓乙? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任末融,我火速辦了婚禮,結(jié)果婚禮上暇韧,老公的妹妹穿的比我還像新娘勾习。我一直安慰自己,他們只是感情好懈玻,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布巧婶。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艺栈。 梳的紋絲不亂的頭發(fā)上英岭,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音湿右,去河邊找鬼巴席。 笑死,一個胖子當著我的面吹牛诅需,可吹牛的內(nèi)容都是我干的漾唉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼堰塌,長吁一口氣:“原來是場噩夢啊……” “哼赵刑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起场刑,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤般此,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后牵现,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铐懊,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年瞎疼,在試婚紗的時候發(fā)現(xiàn)自己被綠了科乎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡贼急,死狀恐怖茅茂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情太抓,我是刑警寧澤空闲,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站走敌,受9級特大地震影響碴倾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掉丽,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一跌榔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧机打,春花似錦矫户、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柑蛇。三九已至,卻和暖如春驱闷,著一層夾襖步出監(jiān)牢的瞬間耻台,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工空另, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盆耽,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓扼菠,卻偏偏與公主長得像摄杂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子循榆,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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

  • HTML模版 之后出現(xiàn)的React代碼嵌套入模版中析恢。 1. Hello world 這段代碼將一個一級標題插入到指...
    ryanho84閱讀 6,221評論 0 9
  • 現(xiàn)在最熱門的前端框架,毫無疑問是 React 秧饮。上周映挂,基于 React 的 React Native 發(fā)布,結(jié)果一...
    sakura_L閱讀 420評論 0 0
  • 現(xiàn)在最熱門的前端框架盗尸,毫無疑問是React柑船。在基于React的React Native發(fā)布一天之內(nèi),就獲得了 50...
    Mycro閱讀 1,005評論 3 6
  • 作者:阮一峰原文地址:http://www.ruanyifeng.com/blog/2015/03/react.h...
    IT程序獅閱讀 1,090評論 0 16
  • LPL的孱弱之謎,一直都是一個謎團历恐。 也一直都是一個大家都在考慮寸癌,都在思考的問題。 為什么我們LPL現(xiàn)在這么弱了弱贼?...
    黃銅刀閱讀 648評論 2 0