学习目的:本节是学习如何使我们的组件具有交互性。
简单的例子:
class LikeButton extends React.Component {
constructor() {
super();
this.state = { liked: false };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({liked: !this.state.liked});
}
render() {
const text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<div onClick={this.handleClick}>
You {text} this. Click to toggle.
</div>);
}
}
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
事件处理和合成事件(Synthetic Events)
使用react可以简单地将事件处理函数通过驼峰式命名的属性来进行传递,正如在普通的html中一阿姨给你,react保证了事件在所有的浏览器中表现一致通过它自己实现的合成事件系统。这意味着,react知道如何根据不同的(浏览器)来实现冒泡及捕获事件,并且这些事件最后传递给事件处理函数时都是一致的。
组件仅仅是状态机
react认为每个组件是一种状态机,一个组件可以有多种状态,通过渲染(render)这些状态,就可以轻易地保持ui一致。
当你更新一个组件的状态(state)时,react会根据状态值来自动渲染出一个新的ui.
state是如何工作的
通知react数据(data
)改变的一个常用的方法是通过调用setState(data, callback)
方法,这个方法可以将data
合并到this.state
然后重新渲染组件。当组件完成渲染之后,(可选的)回调函数将被调用。大部分时候不需要提供回调函数,因为react将保持你的ui可以及时被更新。
什么样的组件需要有state
你的大部分组件仅仅需要从props(属性)中国年获取到data(数据)并且渲染它。但是,有时候你需要回应用户输入、服务器请求或者是时间的变化。在这种情况下,你需要使用state。
但是原则是:尽量保持你的组件是无状态的(stateless),这样你可以将state隔离到最合乎逻辑的地方,并且可以降低冗余,同时可以简化你的应用。通常的做法是首先创造多个无状态的组件,它们仅仅需要渲染数据,然后在它们之上有一个状态组件,然后将这些状态传给子组件。这个状态组件可以包裹所有的交互逻辑,而这些无状态组件仅仅需要渲染数据。
state中需要包含什么
state需要包含一个组件时间处理函数通过改变它来触发ui更新的这些数据。在app中国年,这些数据一般都非常小并且是通过JSON序列化的。当设计一个包含状态的组件时,要考虑状态的最少表达,并且仅仅在render()函数中的this.state中存储这些属性,然后根据这些state来计算你需要的其它信息。这样可以提高你应用的正确率,因为添加或者计算一些冗余的state那么你将需要保持它们同步,这个将会让你的工作变得复杂。
state中不需要包含什么
this.state
中仅仅需要包含最少的必须数据来代表你ui的状态,所以,以下的内容不需要包含在其中。
- 计算值: 不要要预先计算给予state的值,因为你可以在render()中实现这些计算,这种方式同样可以保证你ui表现的一致性。
比如:你有一个数组在state中,你想把它的数组长度渲染成一个string,那么你不需要预先计算出这个数组的length,仅仅需要在渲染的时候计算即可,如this.state.listItems.length + ' list items'
。 - react组件: 根据组件底层的props和状态重建即可。
- 从属性中复制的数据:尽可能地使用props,在state中存储props的一个可行应用是使你可以知道它之前的一个值是什么,因为属性会因为福组件的渲染而发生改变。