每個React組件都有一個state對象,它是一個鍵值存儲對象。在組件被渲染之前,我們可以設置組件的state對象。
打開SearchPage.js,在 SearchPage 類的 render()方法前,加入以下代碼:
~~~
constructor(props) {
super(props);
this.state = {
searchString: 'london'
};
}
~~~
現在組件就有一個state變量了,同時我們在state中存放了一個 searchString:’london’ 的鍵值對象。
然后我們來使用這個state變量。在render方法中,修改TextInput元素為:
~~~
<TextInput
style={styles.searchInput}
value={this.state.searchString}
placeholder='Search via name or postcode'/>
~~~
這將改變 TextInput 的value 屬性,即在TextInput中顯示一個london的文本——即state變量中的searchString。這個值在我們初始化state時指定的,但如果用戶修改了文本框中文本,那又怎么辦?
首先創建一個事件處理方法。在 SearchPage 類中增加一個方法:
~~~
onSearchTextChanged(event) {
console.log(‘onSearchTextChanged’);
this.setState({ searchString: event.nativeEvent.text });
console.log(this.state.searchString);
}
~~~
首先從事件參數event中獲得text屬性,然后將它保存到組件的state中,并用控制臺輸出一些感興趣的內容。
為了讓文本內容改變時這個方法能被調用,我們需要回到TextInput的onChange事件屬性中,綁定這個方法,即新加一個onChange屬性,如以下代碼所示:
~~~
<TextInput
style={styles.searchInput}
value={this.state.searchString}
onChange={this.onSearchTextChanged.bind(this)}
placeholder='Search via name or postcode'/>
~~~
一旦用戶改變了文本框中的文本,這個函數立即就會被調用。
> 注意: bind(this) 的使用有點特殊。JavaScript 中 this
> 關鍵字的含義其實和大部分語言都不相同,它就好比Swift語言中的self。bind方法的調用使得onSearchTextChanged
> 方法中能夠引用到this,并通過this引用到組件實例。更多內容請參考 MDN page on this。
然后,我們在render方法頂部、return語句之前加一條Log語句:
~~~
console.log('SearchPage.render');
~~~
通過這些log語句,你應該能明白大致發生了什么事情!
返回模擬器,按下Cmd+R,我們將看到文本框中一開始就有了一個london的字樣,當你編輯這段文本后,控制臺中的內容將顯示:

查看上面的截屏,log語句輸出的順序似乎有點問題:
1\. 組件初始化后調用 render() 方法
2\. 當文本被改變, onSearchTextChanged() 被調用
3\. 我們在代碼中改變了組件的state 屬性,因此render()方法會被調用
4\. onSearchTextChanged() 打印新的search string.
當React 組件的狀態被改變時,都會導致整個UI被重新渲染——所有組件的render方法都會被調用。這樣做的目的,是為了將渲染邏輯和組件狀態的改變完全進行分離。
在其他所有的UI框架中,要么程序員在狀態改變時自己手動刷新UI,要么使用一種綁定機制在程序狀態和UI之間進行聯系。就像我另一篇文章?[MVVM pattern with ReactiveCocoa](http://www.raywenderlich.com/74106/mvvm-tutorial-with-reactivecocoa-part-1)所講。
而在React中,我們不再操心狀態的改變會導致那一部分UI需要刷新,因為當狀態改變所有的UI都會刷新。
當然,你也許會擔心性能問題。
難道每次狀態改變時,整個UI都會被舍棄然后重新創建嗎?
這就是React真正智能的地方。每當UI要進行渲染時,它會遍歷整個視圖樹并計算render方法,對比與當前UIKit視圖是否一致,并將需要改變的地方列出一張列表,然后在此基礎上刷新視圖。也就是說,只有真正發生變化的東西才會被重新渲染。
ReactJS將一些新奇的概念應用到了iOS App中,比如虛擬DOM(Document Object Modal,web文檔可視樹)和一致性。這些概念我們可以稍后再討論,先來看下這個App接下來要做的工作。刪除上面添加的Log語句。