Components和Props

Components使得你可以將UI分開(kāi)果覆,變的可以復(fù)用 并且單獨(dú)思考他們的作用和功能炮温。
實(shí)際上玄窝,components就像是javascript的函數(shù)一樣。它接收任意的被稱(chēng)為props的輸入并且返回一個(gè)elements械姻,這個(gè)elements決定了該在屏幕上顯示什么妒蛇。

函數(shù)式Components和類(lèi)式Components

下面這個(gè)簡(jiǎn)單的例子用javascript函數(shù)聲明的方法定義了一個(gè)components:

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

這個(gè) 函數(shù)式的component是合法的因?yàn)樗邮樟艘粋€(gè)props對(duì)象為參數(shù)并且返回了一個(gè)element。我們將這樣定義component的方法稱(chēng)之為函數(shù)式的component因?yàn)樗且粋€(gè)Javascript函數(shù)楷拳。
你也可以用ES6語(yǔ)法的class來(lái)定義一個(gè)component:

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

上面兩種定義components的方法是等價(jià)的绣夺。
但是類(lèi)式的components會(huì)有額外的一些功能,我們將在下一個(gè)章節(jié)討論它們欢揖。

渲染Component

前面陶耍,我們僅僅遇到了用html標(biāo)簽組成的element:

const element = <div />;

然而,element也可以用我們自定義的component組成:

const element = <Welcome name="Sara" />;

當(dāng)react看到element中有我們自定義的component時(shí)她混,它將會(huì)降JSX的參數(shù)打包成一個(gè)對(duì)象傳遞給component烈钞,我們稱(chēng)這個(gè)被傳遞的對(duì)象為:props。
比如坤按,下面的代碼在頁(yè)面上渲染了一行“Hello毯欣,Sara”的文字:

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

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

讓我們理一理上面這個(gè)例子:

  1. 我們用ReactDOM.render()這行代碼渲染了<Welcome name="Sara" />這個(gè)element。

2.React將參數(shù)打包為{name: 'Sara'}這個(gè)對(duì)象當(dāng)作props傳遞給Welcome這個(gè)component晋涣。

3.我們自定義的Welcome組件返回了<h1>Hello, Sara</h1>這個(gè)element仪媒。

4.React立即將這個(gè)element渲染到DOM中。

注意谢鹊,一般首字母大寫(xiě)的標(biāo)簽代表我們自定義的component,比如:<div />代表了普通的html標(biāo)簽留凭,而<Welcome>標(biāo)簽代表了一個(gè)自定義組件佃扼。

組合化的Components

components可以將其他components作為他的輸出,這一特性使得我們可以重復(fù)利用以及定義了的componets蔼夜。一個(gè)按鈕兼耀,一個(gè)表單,一個(gè)對(duì)話(huà)框等等求冷,在react中它們都被定義為components瘤运。
比如,我們可以創(chuàng)建渲染多次Welcome組件的應(yīng)用:

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

特別的匠题,一個(gè)react應(yīng)用通常會(huì)有一個(gè)單獨(dú)的Component在它的頂端拯坟。然而,如果你需要將react的應(yīng)用合并到一個(gè)已經(jīng)存在的應(yīng)用中韭山,你就需要用button這些最基本的component自底而上的創(chuàng)建一個(gè)component郁季。

注意:Components必須返回一個(gè)單獨(dú)的element冷溃,這也是為什么我們用<div>將返回的element包裹起來(lái)的原因。

提取Components

不要害怕將一個(gè)components分割成幾個(gè)更小的components梦裂。比如似枕,思考這個(gè)Comment組件:

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

它接受了author, text, date作為props,在頁(yè)面上渲染了一個(gè)comment頁(yè)面年柠。這個(gè)components會(huì)很難被改變凿歼,而且難以被復(fù)用。讓我們將它里面的一些元素抽象成components冗恨。
首先毅往,我們先抽象出Avatar:

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

Avatar不知道它被渲染進(jìn)哪里。這就是我們?yōu)槭裁匆獙⑵鋮?shù)定義為user而不是author派近。
現(xiàn)在我們可以將Comment簡(jiǎn)化一下了:

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

接下來(lái)攀唯,我們抽象出UserInfo:

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

現(xiàn)在,Comment被進(jìn)一步簡(jiǎn)化了:

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

抽象出components可能在一開(kāi)始被認(rèn)為是雞肋渴丸,但是在一個(gè)復(fù)雜的app中這種方式是極為重要的侯嘀,因?yàn)樗峁┝丝蓮?fù)用的組件,大大簡(jiǎn)化了整個(gè)app的復(fù)雜度谱轨。

Props是只讀的

無(wú)論你是用函數(shù)式還是類(lèi)式定義Component戒幔,Component都不能自己修改它的props,思考下面的函數(shù):

function sum(a, b) {
  return a + b;
}

如同上面這樣的函數(shù)被稱(chēng)為純函數(shù)土童,因?yàn)樗粫?huì)試圖去修改它的輸入值诗茎,并且總是返回確定的基于輸入的值。
相反的献汗,下面這個(gè)函數(shù)就不是純函數(shù)敢订,因?yàn)樗淖兞怂妮斎胫担?/p>

function withdraw(account, amount) {
  account.total -= amount;
}

React給予你極大的編碼靈活性,但是有一個(gè)嚴(yán)格的規(guī)則:所有的components必須是純函數(shù)定義
當(dāng)然罢吃,所有的視圖是需要?jiǎng)討B(tài)改變的楚午,在下面的章節(jié)中,我們將會(huì)介紹state的概念尿招。stats允許components改變它的輸入異反饋用戶(hù)的操作矾柜,網(wǎng)絡(luò)響應(yīng)等等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末就谜,一起剝皮案震驚了整個(gè)濱河市怪蔑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丧荐,老刑警劉巖缆瓣,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異篮奄,居然都是意外死亡捆愁,警方通過(guò)查閱死者的電腦和手機(jī)割去,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)昼丑,“玉大人呻逆,你說(shuō)我怎么就攤上這事∑械郏” “怎么了咖城?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)呼奢。 經(jīng)常有香客問(wèn)我宜雀,道長(zhǎng),這世上最難降的妖魔是什么握础? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任辐董,我火速辦了婚禮,結(jié)果婚禮上禀综,老公的妹妹穿的比我還像新娘简烘。我一直安慰自己,他們只是感情好定枷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布孤澎。 她就那樣靜靜地躺著,像睡著了一般欠窒。 火紅的嫁衣襯著肌膚如雪覆旭。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天岖妄,我揣著相機(jī)與錄音型将,去河邊找鬼。 笑死衣吠,一個(gè)胖子當(dāng)著我的面吹牛茶敏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缚俏,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贮乳!你這毒婦竟也來(lái)了忧换?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤向拆,失蹤者是張志新(化名)和其女友劉穎亚茬,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體浓恳,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刹缝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年碗暗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梢夯。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡言疗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出颂砸,到底是詐尸還是另有隱情噪奄,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布人乓,位于F島的核電站勤篮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏色罚。R本人自食惡果不足惜碰缔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戳护。 院中可真熱鬧金抡,春花似錦、人聲如沸姑尺。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)切蟋。三九已至统捶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間柄粹,已是汗流浹背喘鸟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驻右,地道東北人什黑。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像堪夭,于是被迫代替她去往敵國(guó)和親愕把。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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