ReactJS修煉之路(三):props vs state

一,前言

初學rails和ReactJS不久,也分別在看rails和ReactJS的官方文檔,至於這兩者的輕重緩急,公司裏帶我的同事是這樣說的:

“先看React的文檔吧,相對rails來說,React的開發思路更繞,也可以說是React的設計思路更加新穎。”

確實,一開始上手React很容易就學會了怎麼寫交互性控件,能實現數據的展示和動態更新,後來發現這只是個開始。我還沒形成很清晰的React組件開發思路,裏面有很多很模糊的地方。下面說說我的困惑:

  • props和state的區別在哪?
  • 爲什麼不能直接修改props的值?

這段時間看了一些文檔和博客,對這些問題有了一定的瞭解,props vs state這篇博客說得比較全面,特地翻譯了一下,希望能幫到大家。

二,譯文

從我們開始使用React在uberVU (現在是 Hootsuite)重建UI起,開發者問得最多的問題大概是:

props和state的具體區別在哪?

理解他們如何工作相當容易,特別是在對應的上下文中,但在概念上理解他們也有點困難。首先困惑着我們的是,他們都有抽象的術語和相同的值,卻有着很不一樣的規則。

背景

一個組件的主要責任是將原始數據轉化爲豐富的HTML,請記住這點。props和state共同構成原始數據,原始數據構成HTML。你可以說 props 和 state 是一個組件render()函數的輸入數據,所以我們需要深入進去看看每個數據類型代表什麼以及從哪裏來的。

共同點

在區分props和state之前,我們先看看這兩者的共同點:

  • props和state都是 純 JS 對象
  • props和state的改變都會觸發render函數來更新界面
  • props和state都是確定的。 如果你的組件在相同的props和state的組合下產生不同結果,那一定是哪裏錯了。

深入看看

如果一個組件需要在某個時間點改變某個屬性,那該屬性應設爲state,否則應設爲組件的prop。

props

props (properties的簡稱) 是一個組件的 配置選項props是由上到下指定且不可改變的。

一個組件不能改變自身的props, 但要負責設置子組件的 props

state

當組件加載時,state有一個默認值,後來state會不定期地改變(主要是用戶行爲觸發的)。state是每一時間點組件狀態的代表-快照。

一個組件在內部管理自己的state,除了設置子組件的state之外,該組件與其子組件的state沒有任何聯繫。你可以認爲state是私有的。

改變 propsstate

- props state
能否從父組件獲取初始值? Yes Yes
能否被父組件改變? Yes No
能否在組件內設置默認值?* Yes Yes
能否在組件內改變? No Yes
能否設置子組件的初始值? Yes Yes
能否在子組件中改變? Yes No

*注意:propsstate 從父組件獲取的初始值都會被在組件內設置的默認值覆蓋。

組件是否應該有state?

state 是可選項,不是React強制實現的。因爲state增加了組件的複雜度同時降低了組件的可預見性,所以沒有state的組件 要略勝一籌。即便在一個交互式應用中,你顯然離不開state,你也要避免有太多的有狀態化組件(含有state的組件)。

組件類型


  • 無狀態組件 — 只有 props, 沒有 state。 除去render() 函數和所有圍繞props的邏輯之外,沒有什麼要關心的地方。這使他們易於理解且易於測試
  • 有狀態組件 — 既有 props 又有 state。也被稱作狀態管理者 。他們負責客戶端-服務器通信(通過XHR, web sockets, 等),數據處理和給用戶行爲反饋。

譯者標註爲重要內容:這些邏輯實現應該封裝在一個含有中等數量state的有狀態組件中,而所有可視化和格式化的邏輯實現應該儘可能封裝在多個無狀態組件中。

一些討論

三,補充

補充官網文檔裏如何判別某一變量應設爲state還是prop:

哪些組件應該有 State?

大部分組件的工作應該是從 props 裏取數據並渲染出來。但是,有時需要對用戶輸入、服務器請求或者時間變化等作出響應,這時才需要使用 State。

嘗試把儘可能多的組件無狀態化。 這樣做能隔離 state,把它放到最合理的地方,也能減少冗餘,同時易於解釋程序運作過程。

常用的模式是創建多個只負責渲染數據的無狀態(stateless)組件,在它們的上層創建一個有狀態(stateful)組件並把它的狀態通過 props 傳給子級。這個有狀態的組件封裝了所有用戶的交互邏輯,而這些無狀態組件則負責聲明式地渲染數據。

哪些 應該 作爲 State?

State 應該包括那些可能被組件的事件處理器改變並觸發用戶界面更新的數據。 真實的應用中這種數據一般都很小且能被 JSON 序列化。當創建一個狀態化的組件時,想象一下表示它的狀態最少需要哪些數據,並只把這些數據存入 this.state。在 render() 裏再根據 state 來計算你需要的其它數據。你會發現以這種方式思考和開發程序最終往往是正確的,因爲如果在 state 裏添加冗餘數據或計算所得數據,需要你經常手動保持數據同步,不能讓 React 來幫你處理。

哪些不應該作爲 State?

this.state 應該僅包括能表示用戶界面狀態所需的最少數據。因此,它不應該包括:

  • 計算所得數據: 不要擔心根據 state 來預先計算數據 —— 把所有的計算都放到 render() 裏更容易保證用戶界面和數據的一致性。例如,在 state 裏有一個數組(listItems),我們要把數組長度渲染成字符串, 直接在 render() 裏使用 this.state.listItems.length + ’ list items’ 比把它放到 state 裏好的多。
  • React 組件: 在 render() 裏使用當前 props 和 state 來創建它。
  • 基於 props 的重複數據: 儘可能使用 props 來作爲惟一數據來源。把 props 保存到 state 的一個有效的場景是需要知道它以前值的時候,因爲未來的 props 可能會變化。

四,更多資料

五,總結

看完上面的文章之後,我解決了幾個問題:

  • props和state在使用場合的區別
  • 怎樣在應用中合理區分有狀態組件和無狀態組件

這是第一次翻譯別人的文章,我覺得要比自己看幾遍理解得都要深刻,所以這是一次好的嘗試。希望自己能找到更多好文章,學得更多。

發佈了32 篇原創文章 · 獲贊 87 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章