從上一篇 (連結在下面) 知道了怎麼建立一個元件,還有父元件傳值到子元件的方法

React 初學者筆記與教學 (二) - Virtual DOM、元件的建立與傳接值

但是要注意一下,上面文章所講的傳接值指的是單向 (只有父往子傳) 而不是雙向

但是網頁元件免不了要跟使用者互動啊,這個時候就需要用到 state 這個狀態管理的東東 

但依照官網所說的使用時有些注意事項,以下就來了解一下~

 

還是堅持要有目錄:

1. Reactive state (響應狀態)

2. State 使用的時機

3. 哪些不應該作為 State?

4. 針對 State 比較好的開發模式

5. 其他使用注意事項

6. 跟 State 有關的其他操作

7. 參考資料

 

Reactive state (響應狀態)

React 有個特點是將整個元件看成一個狀態機(State Machines),這個 State Machines 就是這篇的主題

在預設的情況下,從父元件傳值到子元件之後,子元件會使用 props 來做接值使用

每一個元件都會根據自己的 props 來 render 自己一次,但是因為 props 都是從父元件來的屬於父元件

所以 props 是不能更改的,此時就要使用 state 來達到互動的目的

使用 state 之後工作方式會變成這樣:

我們讓元件一開始有一個初始的狀態,然後隨著使用者的互動會讓狀態改變,此時就會觸發讓 UI 重繪 (render) 就會達到我們雙向溝通的目的

基於上面所說的,來看一下官網的範例,還是看程式最好懂了!

var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);

 

上面程式裡面的 getInitialState() 方法就是用來設定初始狀態用的,這邊預設 liked : false

所以 render 之後 UI 出現 You haven't liked this. Click to toggle. 的文字在頁面上

然後滑鼠 onClick 就觸發 handleClick,裡面的 this.setState({liked: !this.state.liked}); 去改變了狀態

因為改變了狀態所以也觸發了元件重新 render,所以頁面上文字變成  You like this. Click to toggle.

換句話說~

之後我們只要更新元件的 state 就可以了,不需要再去操作DOM了,react 會自己幫我們處理


然後官網中對 state 的使用有一些提醒

https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html

State 使用的時機:

state 主要是用在要與使用者互動的地方,像頁面上輸入的文字方塊,或需要動態呈現 ajax 回來後的資料

而太頻繁的使用 state 代表你可能需要承擔元件 render 後出現錯誤的風險

(但以我現在的程度還不知道是什麼風險 = =)

所以如果網頁不需要與使用者互動就不要使用 state,然後如果有邏輯的運算不要放在 state 中

盡量在 render 裡面做掉,可以更確保UI與數據的一致性

 

以下是官網說的:(居然有簡體中文版,幫大家轉成繁中了)

https://facebook.github.io/react/docs/interactivity-and-dynamic-uis-zh-CN.html

哪些不應該作為 State?

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

計算所得數據

不要擔心根據 state 來預先計算數據 —— 把所有的計算都放到 render() 裡更容易保證用戶界面和數據的一致性。例如,在 state 裡有一個數組(listItems),我們要把數組長度渲染成字符串, 直接在 render() 裡使用 this.state.listItems.length + ' list items' 比把它放到 state 裡好的多。

React 組件

在 render() 裡使用當前 props 和 state 來創建它。
基於 props 的重複數據: 儘可能使用 props 來作為實際狀態的源。把 props 保存到 state 的一個有效的場景是需要知道它以前值的時候,因為 props 可能因為父組件重繪的結果而變化。

(老實講雖然是中文,但我看不太懂,大家自己去體會)

 

針對 State 比較好的開發模式

官網提到比較好的開發模式,是建立多個沒有使用 state (無狀態) 的元件

然後在它們的上層有一個使用 state 的元件,父元件再透過 props 來把狀態傳到子元件裡面去 render 

這樣做的話父元件就會是專門負責管理 state 的邏輯,而子元件就只要負責重繪頁面即可

 

其他使用注意事項:

另外不要直接使用 this.state 去更改 state,如果要異動的話要使用 setState(data, callback)

這樣 setState 才會通知相應的 render 重繪,不然 react  不會知道 state 被改了

然後 setState(data, callback) 最後也會合併 data 到  this.state 去

並且在重繪完頁面之後就會執行 callback (當然也可以不傳)

 

跟 State 有關的其他操作:

shouldComponentUpdate()

可以用來決定是否要 render,返回 true = 要,false = 不要

這個方法在第一次 render 的時候不會被執行,執行時間落在收到 this.state 跟要 render 之間

用法像這樣:

shouldComponentUpdate: function(nextProps, nextState) {
    return nextProps.id !== this.props.id;
}

componentWillUpdate()

在收到 props or state 之前會先被呼叫使用,這個方法是用來做一些更新 state 前的準備

但不能在這使用 this.setState() 設定 state,如果要更新要使用 componentWillReceiveProps

componentWillReceiveProps()   (其實這個是跟 props 有關,state 沒有相關的用法)

在收到 props 時會 render 之前被呼叫,要注意在這邊使用 this.setState() 不會引發 render 

 

參考資料:

如果想要看更多 state 應用例子的話,有些範例可以參考:

http://tutorialzine.com/2014/07/5-practical-examples-for-learning-facebooks-react-framework/

=============================================================

https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html

https://facebook.github.io/react/docs/interactivity-and-dynamic-uis-zh-CN.html

https://medium.com/react-tutorials/react-state-14a6d4f736f5#.2neq3gswr
 

快快樂樂學 React  系列

=========================================

React 初學者筆記與教學 (一) - 新手村搞定開發環境

React 初學者筆記與教學 (二) - Virtual DOM、Component (元件) 的建立與傳值

React 初學者筆記與教學 (三) - State 的介紹與使用方式,讓你的元件可以跟使用者互動!

React 初學者筆記與教學 (四) - 使用 React.PropTypes 來驗證元件屬性

 

 

創作者介紹
創作者 小雕 的頭像
小雕

小雕雕的家

小雕 發表在 痞客邦 留言(0) 人氣()