React讀書筆記-組件

本文僅作為個人學習React的筆記,文中省略了基礎的知識點和術語。在閱讀本文前,默認已經準備好了React的運行環境。

本文重點記錄React的組件部分,且不使用ES6的特性。

如何創建一個組件?

創建一個組件使用React.createClass(object)方法,作為組件,該方法返回的變量名稱必須以大寫字母開頭。

示例:

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

在React.createClass參數必須是一個JS對象,其必須實現一個名為render方法,該方法的返回值是一個只包含一個根節點的Dom對象(可以包含自定義組件)。

組件的屬性 props

組件的屬性可以使用this.props來獲取,該屬性值來源于組件調用時的定義,屬性在定義后就不能被修改,除非重新生成組件。

屬性定義示例:

ReactDOM.render(
  <HelloMessage name="zsea.Message" />,
  document.getElementById('example')
);

其中,組件包含名稱為name屬性,可以能過this.props.name來獲取。

特殊屬性:props.children

該屬性為組件的子對象,若子對象只有一個,該值為一個JS對象,若有多個,則為JS數組。當為JS數組時,呈現的子對象必須包含key屬性。
為了簡化操作,React提供了方法React.Children.map(children,function(){})用于遍歷子對象,使用該方法遍歷時,不需要區分是JS數組還是JS對象。

示例:

var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        React.Children.map(this.props.children, function (child,_index) {
          return <li key={_index}>{child}</li>;
        })
      }
      </ol>
    );
  }
});
ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);

屬性驗證 PropTypes

為保證組件被正確使用,React引入了propTypes,用于對屬性進行校驗,同時,React.PropTypes提供了大量的驗證器來驗證傳入數據的有效性。當向 props 傳入無效數據時,JavaScript 控制臺會拋出警告。為了性能考慮,建議只在開發環境驗證 propTypes。

下面用例子來說明不同驗證器的區別:

React.createClass({
  propTypes: {
    // 可以聲明 prop 為指定的 JS 基本類型。默認
    // 情況下,這些 prop 都是可傳可不傳的。
    optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,
    optionalSymbol: React.PropTypes.symbol,

    // 所有可以被渲染的對象:數字,
    // 字符串,DOM 元素或包含這些類型的數組(or fragment) 。
    optionalNode: React.PropTypes.node,

    // React 元素
    optionalElement: React.PropTypes.element,

    // 你同樣可以斷言一個 prop 是一個類的實例。
    // 用 JS 的 instanceof 操作符聲明 prop 為類的實例。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 你可以用 enum 的方式
    // 確保你的 prop 被限定為指定值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // 指定的多個對象類型中的一個
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // 指定類型組成的數組
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // 指定類型的屬性構成的對象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // 特定形狀參數的對象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // 你可以在任意東西后面加上 `isRequired`
    // 來確保 如果 prop 沒有提供 就會顯示一個警告。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意類型
    requiredAny: React.PropTypes.any.isRequired,

    // 你可以自定義一個驗證器。如果驗證失敗需要返回一個 Error 對象。
    // 不要直接使用 `console.warn` 或拋異常,
    // 因為這在 `oneOfType` 里不起作用。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

React也提供了針對子對象的驗證器

React.PropTypes.element 你可以指定僅有一個子級能被傳送給組件。

var MyComponent = React.createClass({
  propTypes: {
    children: React.PropTypes.element.isRequired
  },
  render: function() {
    return (
      <div>
        {this.props.children} // 這里必須是一個元素否則就會警告
      </div>
    );
  }
});

默認屬性 getDefaultProps

當父級沒有傳入 props 時,getDefaultProps() 可以保證 this.props.value 有默認值,注意 getDefaultProps 的結果會被緩存。得益于此,你可以直接使用 props,而不必寫手動編寫一些重復或無意義的代碼。
該接口要求返回一個JS對象。

示例:

var ComponentWithDefaultProps = React.createClass({
  getDefaultProps: function() {
    return {
      value: 'default value'
    };
  }
});

組件的狀態 state

組件的屬性在被定義后,是不允放被修改的。但是,React同時也提供了組件的狀態,狀態是允許被在內部修改的。
獲取組件狀態使用this.statethis.state是一個JS對象。

示例:

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello Message {this.state.time}!</h1>;
  }
});

其中,time為組件的一個狀態。

狀態的修改 setState

在語言層面,我們可以直接使用'='來修改組件的狀態(this.state),但是,這種方法的修改并不能使組件觸發render,修改后的狀態并不能反映在WEB界面上。
Reace為我們提供了統一的狀態修改方法:this.setState(state),參數state是一個JS對象,其中只需要標識需要被修改的對象,而this.state中已經存在的非同名對象不會被覆蓋。該方法僅能在組件內部調用。

初始狀態 getInitialState

狀態是由組件內部進行控制,在沒有任何方法調用前,React提供了一個接口用于組件狀態的初始化:getInitialState,該接口要求返回一個JS對象。

示例:

var HelloMessage = React.createClass({
  getInitialState:function(){
      return {time:'2016-12-23'};
  },
  render: function() {
    return <h1>Hello Message {this.state.time}!</h1>;
  }
});

在getInitialState接口中,可以使用組件的屬性值做為組件的狀態。

示例:

var HelloMessage = React.createClass({
  getInitialState:function(){
      return {time:this.props.time};//time屬性作為組件的time的狀態值
  },
  render: function() {
    return <h1>Hello Message {this.state.time}!</h1>;
  }
});

總結

一個React組件,提供了兩個接口、一個方法、三個對象。

兩個接口

  • render
  • getInitialState

其中render用于組件的呈現,在調用方法this.setState(state)時會被自動調用。getInitialState用于返回組件內部的初始狀態,可以使用屬性值作為組件狀態。

一個方法

  • setState(state)

該方法用于重新設置組件的狀態值,并且根據需要觸發render

三個對象

  • state
  • props
  • propTypes

其中state存儲的組件狀態,可以能過setState進行修改;

props存儲的組件屬性,不能被修改;同時,props包含一個特列對象:props.children,該對象中包含的時子對象。

propTypes為一個JS對象,該對象用于校驗組件的屬性是否正在確。

參考資料

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

推薦閱讀更多精彩內容

  • 原教程內容詳見精益 React 學習指南,這只是我在學習過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,851評論 1 18
  • 目前,react組件有三種寫法,分別是es5的createClass寫法,es6的class寫法,以及statel...
    ZoomFunc閱讀 1,742評論 0 1
  • 深入JSX date:20170412筆記原文其實JSX是React.createElement(componen...
    gaoer1938閱讀 8,093評論 2 35
  • 自己最近的項目是基于react的,于是讀了一遍react的文檔,做了一些記錄(除了REFERENCE部分還沒開始讀...
    潘逸飛閱讀 3,447評論 1 10
  • 文/鴻運 我是一片浮云 漂浮在天地萬物之間 隨季節的變遷 去抒發自己的情感 春風化雨 我便滋潤萬物的心田 去萌發它...
    HONGYUNDANGTOU閱讀 547評論 21 16