[React Native] React 中的組件和屬性(Components and Props)

目錄

  • 1.組件(Components)
    • 1.1 什么是組件
    • 1.2 定義組件
    • 1.3 渲染組件
    • 1.4 組合組件
    • 1.5 封裝組件
  • 2.屬性(Props)

1. 組件(Components)

1.1 什么是組件

組件能讓你將 UI 拆分成各個獨立的、可復用的子單元。組件就像 JavaScript 函數(shù)一樣,接受參數(shù)(也就是 props),返回屏幕上要渲染的 React 元素。各個組件內(nèi)部維護自己的狀態(tài)和 UI,當狀態(tài)發(fā)生改變時,React 會自動重新渲染整個組件,多個組件一起協(xié)作共同構成了 React 應用。

1.2 定義組件

① 以函數(shù)的形式來定義組件

          function Welcome(props) {
              return <h1>Hello, {props.name}</h1>;
          }

② 以類(ES6 class)的形式來定義組件

         class Welcome extends React.Component {
             render() {
                 return <h1>Hello, {this.props.name}</h1>;
             }
         }

1.3 渲染組件

組件可以當作 React 元素來用。而且我們可以通過 Props 來向組件中傳遞參數(shù):

         function Welcome(props) {
             return <h1>Hello, {props.name}</h1>;
         }

        const element = <Welcome name="Sara" />;
        ReactDOM.render(
          element,
          document.getElementById('root')
        );

1.4 組合組件

組件可以互相引用,一個組件中可以在標簽中使用其他組件。

例如, App 組件中就有三個 Welcome 組件:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

1.5 封裝組件

通過將可重用的代碼封裝成一個獨立的組件,可以提高代碼的復用性和可讀性。

什么時候需要封裝組件?
① 大量的重復 UI 代碼;
② 一個組件內(nèi)部有太多的內(nèi)容,相當復雜時,就需要抽取一部分代碼出來。

舉個例子,我們現(xiàn)在有一個 Comment 組件,通過 props 接收了三個參數(shù) author (object), text (string), 和 date (date) ,用來顯示一條評論:

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

很顯然,這里的代碼嵌套太多,難以閱讀,而且里面的一些代碼不能被重用。所以,我們可以嘗試抽取一些代碼進行組件封裝。
第一步,我們先封裝一個 Avatar 組件:

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

Comment 組件中的代碼就變成了

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

即便這樣,Comment 中的代碼感覺還是有點多,我們還可以再進一步抽取封裝一個 UserInfo 組件:

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}

這樣 Comment 組件中的代碼就變得非常簡單了:

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

2. 屬性(Props)

什么是屬性?大多數(shù)組件在創(chuàng)建時就可以使用各種參數(shù)來進行定制,用于定制的這些參數(shù)就稱為屬性(props)。

屬性是用來給外部向組件內(nèi)部傳值的,組件的內(nèi)部通過讀取 props 來決定如何展示以及處理一些邏輯。

屬性是只讀的,不要試圖在組件內(nèi)部修改外部傳遞進來的 props。

React 組件就像 pure function 一樣(不可以修改傳入的參數(shù)):

// This is a pure function
function sum(a, b) {
  return a + b;
}

而不像 impure function(可以修改傳入的參數(shù)):

// This function is impure because it changes its own input.
function withdraw(account, amount) {
  account.total -= amount;
}

關于 props 使用的完整示例代碼:

import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

class Greeting extends Component {
  render() {
    return (
      <Text>Hello {this.props.name}!</Text>
    );
  }
}

class LotsOfGreetings extends Component {
  render() {
    return (
      <View style={{alignItems: 'center'}}>
        <Greeting name='Rexxar' />
        <Greeting name='Jaina' />
        <Greeting name='Valeera' />
      </View>
    );
  }
}

AppRegistry.registerComponent('LotsOfGreetings', () => LotsOfGreetings);

規(guī)則:

  1. 組件名必須以大寫字母開頭。
  2. 所有的 React 組件都必須想 pure function 一樣對待它的 props——不要在組件內(nèi)部修改 props。
  3. 組件必須返回一個單獨的根元素。就像在上文中 4.1 部分的示例代碼一樣,App 組件返回時,通過一個 <div> 標簽將 3 個 < Welcome /> 標簽包起來了。

延伸閱讀:

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

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

  • In this article we will discuss how to use Higher Order C...
    人頭原子彈閱讀 584評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,748評論 25 708
  • 你以,側影示我 染一身、琉璃白 琉璃在,婚禮的殿堂 曲調深婉,用情致切 這不是幻想在現(xiàn)場 也能想象出,那畫面、情景...
    云水禪心1997閱讀 203評論 0 0
  • 答案很簡單,我希望找到一個做好人的原則。 從小便希望做一個好人,一個有益于別人的人,于是一直努力去做,卻發(fā)現(xiàn)經(jīng)常事...
    常慚愧入世修行者閱讀 265評論 0 0
  • 每次往返家的路上總會思緒萬千,耳機里《忘了我》唱的撕心裂肺,忘了我,忘了我…… 和媽媽談完心,所有的委屈所有的難過...
    卟二_6629閱讀 250評論 0 2