组件状态
最后更新于:2022-04-01 04:30:12
每个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的字样,当你编辑这段文本后,控制台中的内容将显示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-27_562f20d36171c.png)
查看上面的截屏,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语句。