原文在此:A Visual Guide to State in React
React的"state"概念是比較難學的內容,不僅僅是因為React中放置了state,而是實際上,React是因此而生存. Redux也和React的state直接相關. 我希望在本文中能把一些困惑的內容講清楚
你一直在使用的這個詞...
實際上,這個詞"state"有點模稜兩可.某種意義上,"state"意思是當前螢幕上的資料表現. 它可以是"loading" 狀態,或者是一個"error" 狀態. 這裡的解釋和React裡的state解釋還不太一樣.
從React的角度上,"state"是一個代表了應用中可以變化的部分.每個元件都在this.state
中儲存了自己的state
簡而言之,如果需要應用可以做任何事-如果想新增互動,新增和刪除內容,輸入輸出日誌-都要包含在state中.
React的state是什麼樣子
假設你有這樣一個應用,在特定的時間,如下圖:
看這張圖,挑出所有可以改變的部分(基本上包含了所有的東西)
現在我們可以給這些內容定義名字(時間,電池用量,室內溫度,室外溫度),用JavaScript物件描述如下:
{
currentTime: "2016-10-12T22:25:42.564Z",
power: {
min: 0,
current: 37,
max: 100
},
indoorTemperature: {
min: 0.0,
current: 72.0,
max: 100.0
},
outdoorTemperature: {
min: -10.0,
current: 84.0,
max: 120.0
},
tempUnits: "F"
}
複製程式碼
這個物件描述了應用的整個state,也就是React state的用途.
注意一點,欄位沒有和UI完全契合. 沒關係,日期很容易格式化,可以用最大值這最小值畫出圖形的尺度,等等.
這一點保持不變:改變了state
物件就會改變app的表現.
讀者 foobarwtf指出 min
和max
不會改變,因為他們從不改變,為什麼還要在state
中出現? 常見的做法是從伺服器獲取響應輸入到state.如果你遠端獲取當前溫度資料,資料就包含了min
,max
.最好和state中其他資料一起儲存. 因為看起好像資料是固定不變的.但是如何伺服器改變了標準怎麼處理? 如果使用者使用了一個200A的電力系統?等等問題.
所以:state通常儲存這個可以變化的東西,也可以放一些從伺服器獲得的易改變的資訊.
如何對State進行修改
如果state中任何一項發生變化,例如溫度飆升到75°,應用應該重新整理反映出變化.這就是React根據state所做的工作:重新渲染整個app
這裡是state可能發生變化的原因:
- 使用者點選按鈕
- 從伺服器獲得了資料-websocket的資訊,或者是之前請求返回的響應資料
- 定時器終止-或許是每5秒更新螢幕上的當前時間
那麼,React是如何知道state發生改變的? 持續輪訓變化?像Angular一樣觀察事件?不是,一點也不神奇.
React知曉State的變化是因為你在元件內部通過this.setState
顯式的告訴元件應該怎麼更新.換句話說,沒有什麼魔法,React只是按照你設定的去做更新.
計數器中的State變換
上面的家庭檢測應用是一個state實戰的絕好例項,但是我們會返回簡單的"counter"應用,看看state是如何變化的.
這裡是counter的工作方式:
- 數字顯示從0開始
- 你點選按鈕(會呼叫設定的
handleClick
函式) - 計數器增加1(呼叫
setState
完成這個任務) - React 根據state的變化重新渲染app
程式碼展示
快速瀏覽:
- React以物件的形式儲存state
- 你可以通過呼叫
setState
來改變物件 - 每次呼叫
setState
時,React會重新渲染 這裡有兩個地方要注意: - 不能直接用
this.state
,一定要用this.setState
- state的變化時非同步的,所以如果你想從
this.state
中立即獲取this.setState
的變化,可能還沒有反應出來.
用Debugger把程式碼視覺化
細節,細節
在本文中,我說過state是一個描述整個app的單一物件-但是在實際中,它需要分成更小的片段. 最好的方法是把它們儲存在"container"元件中,和"presentational"元件隔離.
如果你正在使用Redux,你實際就有一個描述整個app的大 state物件. Redux的基本做法就是保持一個大的代表整個應用的state, 接著reducer和mapStateToProps
把它切分成每個元件需要的塊.
我希望本文能讓你理解state的內容.