[譯] 組件、Prop 和 State

原文連接: learnreact.design/2017/08/16/…react

喜歡理由: 插圖大愛 生動有趣 視角獨到編程

特別鳴謝: 原做者 Linton Ye 的傾情校對windows

系列博客: 用通俗的語言和塗鴉來解釋 React 術語react-native

今天咱們來學習 React 裏最重要的三個概念: 組件、prop 和 state ,以及 prop 和 state 之間的區別。ionic

如同以前的文章,我仍是會嘗試用通俗的語言來解釋這些概念。所以,閱讀本文一樣不須要任何 JavaScript 基礎。post

在本章中你根本找不到任何 JavaScript 代碼,我將用一種簡單的標識語言來幫助你理解主要的概念,在之後的文章裏我再用 JavaScript 代碼詳細講解。一步一個腳印嘛,我相信這種方法對於學習 React 或其餘技術都是有效的,尤爲是當你沒有太多編程經驗時。要是將 React 的概念和 JavaScript 的細節混在一塊兒的話,極可能會令你不知所措!學習

學習目標

當你讀完本文後但願你能從新回到這裏,並可以輕鬆回答如下問題:編碼

  • 什麼是 prop ?
  • 什麼是 state ?
  • 什麼時候使用 prop ?什麼時候使用 state ?
  • 如何讓例子的窗戶能夠打開和關閉?
  • 你能寫出 Domo 帽子那個例子的僞代碼嗎?

蓋房子

要想理解這些概念是什麼以及如何使用它們,咱們先來寫一個小示例。就蓋個房子如何?(點擊門有驚喜)spa

查看由 focuser (@focuser) 在 CodePen 編寫的 Demo : React 小屋翻譯

組件

若是你還記得咱們在前面文章中所討論過的,組件的概念是 React 的三大支柱之一。使用 React 開發應用基本都是在使用組件。

第一步是將 UI 分解成多個組件。例如,咱們能夠這樣來拆分房子:

如今來編碼!

House:

  <div> <Roof /> // 房頂 <Wall /> // 牆 <Window /> // 窗 <Door /> // 門 </div>
複製代碼

等一下,怎麼看起來這麼像 HTML ?沒錯!React 的部分代碼看上去就是很是像 HTML ,其實就是這樣設計的,這是爲了讓 Web 設計師理解和編寫 React 代碼更容易一些。太貼心了!

所以,在上面的代碼中,咱們使用 <div> 做爲容器,這基本和 HTML 中是同樣的。而像 RoofWall 這樣的標籤是咱們即將定義的自定義標籤/組件。

舒適提示: 上面的代碼並不是實際的 React 代碼,甚至連 JavaScript 都算不上。暫時,咱們只使用這種寬鬆的語法來介紹概念。一旦你理解這些概念後,咱們再來學習 JavaScript 的細節並將上述概念轉換成真實代碼。

爲了讓這個例子更容易理解一些,我再簡化一下: 從如今開始,咱們來寫一個超級簡單的 Web 應用,連圖片都不用,只顯示文字。

例如,Roof 其實就是一個裏面有文字的 div :

Roof:

  <div>roof</div>
複製代碼

其餘組件也是如此,都是隻有文字的 div 而已。首先,咱們來看下房子的完整的 React 風格的代碼:

House:

  <div> <Roof /> <Wall /> <Window /> <Door /> </div>  

Roof:

  <div>roof</div>

Wall:

  <div>wall</div>

Window:

  <div>window</div>

Door:

  <div>door</div>
複製代碼

這沒什麼很差理解的,是吧?House 是由 RoofWallWindowDoor 組成的,這些都是純文本構成的組件。

最後,React 生成的 HTML 以下所示:

<div>
  <div>roof</div>
  <div>wall</div>
  <div>windows</div>
  <div>door</div>
</div>
複製代碼

使用 Props 來配置屋頂的顏色

想象一下,咱們將規格說明書發給一個工廠,這個工廠負責代工全部的零部件。在規格說明書中,咱們能夠告訴工廠每一個部件的固有屬性,好比屋頂的顏色、門的形狀,等等。在按照咱們的要求將屋頂和門生產出來後,它們的屬性不會產生任何變化,屋頂仍是藍色的,門依舊是矩形的。這些屬性壓根不會改變。

在 React 裏,咱們將這些屬性稱之爲 Prop ,即 property 的縮寫。關於 Prop ,你須要記住兩點: 首先,咱們來決定 Prop 的值,並在組件構建以前將其做爲組件設計的一部分。其次,Prop 的值永遠不會改變。

那 prop 在代碼中是怎樣的呢?在 House 組件中,若是咱們想要藍色屋頂的話,只需在 Roof 組件上添加 「color」 屬性。這就比如是在發給工廠的規格說明書中指定顏色。

這有點相似於給 HTML 標籤添加屬性:

House:

  <div> <Roof color="blue"/> ... </div> 複製代碼

Roof 裏面又是怎麼樣使用 prop 的呢?代碼以下所示:

Roof:

  <div>{props.color} roof</div>
複製代碼

就這樣?沒錯!可是有幾點須要注意:

  • 定義組件的 HTML 風格代碼是一個模板,而不是單純的 HTML 標籤。這意味着咱們能夠在其中放置佔位符來改變 HTML 輸出的內容,而沒必要重複編寫不一樣的 HTML (還記得 Domo 的帽子嗎?這就是佔位符的概念!)。在這個示例中,<Roof color="blue" /> 生成的 HTML 是 <div>blue roof<div>,而 <Roof color="red" /> 生成的是 <div>red roof</div>,以此類推。
  • 模板中使用的花括號告訴 React 咱們要在此處使用佔位符來替代純文本。
  • props 能夠看做是 Roof 組件全部屬性值的集合。假設組件是這樣使用的: <Roof color="blue" material="wood" /> ,那麼在 Roof 組件的定義中就可使用 props.colorprops.material

使用 State 來開門

爲組件添加 State

組件還能夠擁有 state 。那麼什麼是 state ?state 是一種能夠在組件建立後更改的數據。

舉個例子,門既能夠開,又能夠關。咱們能夠說門的狀態就是 state ,由於它的值是能夠在門建立後更改的。在這點上,state 與 prop 是不一樣的,prop 是不會改變的,好比門的形狀。

狀態值的改變一般是由外部事件所引發的。在 Web 應用中,這些所謂的外部事件一般包括:用戶輸入了數據,或者從服務端獲取了數據,又或者是定時器的觸發。

下面,咱們來爲門添加 state :

Door:
  State:
    status   // "open" 或 "closed"
  <div>Door is {state.status}</div>
複製代碼

props 相似,state 也是組件內部全部狀態值的集合。所以,咱們能夠在組件定義的模板中使用 state.[something]

接下來,咱們來添加一些處理用戶輸入的「僞代碼」來讓門具備交互性。

Door:
State:
  status // "open" 或 "closed"

  <div>Door is {state.status}</div>
  // 處理用戶輸入
  當開門時
    將 state.status 修改爲 "open"
  當關門時
    將 state.status 修改爲 "closed"
複製代碼

這裏的關鍵點是組件的 state 是隨時間而變化的。模板的輸出,也就是生成的 HTML 會根據 state 的變化而自動改變。

順便說句,不要忘了上面的只是「僞代碼」,而不是 React 代碼。不要嘗試將其複製黏貼到你的項目中!不然你的電腦炸了我不負責……💣

State 是私有的

組件的 state 是私有的。門不管是開仍是關,這都僅僅是門的邏輯。與房子或其餘組件沒有任何關係。事實上,咱們徹底能夠將門從房子中移出去,它仍然能夠本身打開或關閉。

所以,門的狀態只有在 Door 組件內部是可見的。在 Door 組件內,咱們能夠讀取或改寫它的 state 。

House:
  <div> <Door /> ... <!-- 下面這句是錯的 --> <div>The door is {Door.state.status}</div> </div>

Window:
  ...
  <!-- 下面這句是錯的! -->
  將 Door.state.status 修改爲 'open'

Door:
  ...
  <!-- 兄dei,這仍是錯的! -->
  if House.state.正在出售
    房產經紀人就能夠開門
複製代碼

總結

好啦,這就是 prop 和 state 。prop 是組件的配置項,它的值是在組件建立以前就已經決定好了,好比門的形狀和屋頂的顏色就能夠定義爲 prop。prop 的值永遠不會改變。而 state 是組件的私有數據,當組件建立後纔可使用它。好比門的開關狀態能夠包括在 state 裏面。state 會隨着一些外部事件的發生而變化。這些所謂的外部事件一般包括:用戶輸入了數據,或者從服務端獲取了數據,又或者是定時器的觸發。

但…是,咱們尚未開發任何實際的東西啊?一個只顯示純文本的應用能有多大用處呢?至少要學到如何建造本文開頭所說的房子吧?界面裏有東西能夠點纔有用啊?

毫無疑問,要作到這些呢,咱們就須要用 JavaScript 編程了。這個之後再講吧。若是你不喜歡等待,能夠註冊個人課程並經過教學視頻進行學習。

相關文章
相關標籤/搜索