基本用法
在React
中,有一个重要的概念,就是组件的状态state
,它用来表示整个组件的数据模型,是组件渲染时的数据依据。这里,我们首先通过一个简单的示例:计数器,来讲解state
的用法。首先创建这个组件:
import React, { Component } from "react"
import ReactDOM from "react-dom"
class Counter extends Component {
render() {
return (
<div>
<h1>一共点击了0次</h1>
<input type="button" value="+" />
<input type="button" value="-" />
</div>
)
}
}
ReactDOM.render(<Counter />, document.querySelector("#root"))
我们使用h1
元素用来标志用户点击次数,然后提供两个按钮给用户进行点击。当用户点击+
按钮时,次数递增,同理,点击-
按钮,次数递减。
接下来,我们再来看一下如何添加组件的状态,在react
中,状态是通过state
属性来描述的,我们首先在组件中定义这个属性,然后再添加一个count
用来描述用户点击的次数,初始值为0
:
class Counter extends Component {
state = {
count: 0
}
...
}
然后再把这个状态值绑定到h1
元素中,这里我们可以使用表达式来访问这些状态。
<h1>一共点击了{this.state.count}次</h1>
当完成这一步之后,整个组件就变成一个有状态组件了,接下来,就是用户的操作,我们首先给这两个按钮添加点击事件,方法很简单,我们只需要在按钮的元素上添加onClick
属性就可以绑定点击事件,这里表达式中的函数,就是当用户点击按钮时触发的事件句柄。
<input type="button" onClick={() => console.log("in")} value="+" />
<input type="button" onClick={() => console.log("de")} value="-" />
点击之后可以看到控制台已经输出,说明这个函数被调用了。
除了这种直接声明函数的方式以外,我们还可以在组件类内部来定义这个函数。
import React, { Component } from "react"
import ReactDOM from "react-dom"
class Counter extends Component {
state = {
count: 0
}
increment = () => {
console.log("in")
}
decrement = () => {
console.log("de")
}
render() {
return (
<div>
<h1>一共点击了{this.state.count}次</h1>
<input type="button" onClick={this.increment} value="+" />
<input type="button" onClick={this.decrement} value="-" />
</div>
)
}
}
ReactDOM.render(<Counter />, document.querySelector("#root"))
点击之后,我们看到依然成功触发。
接下来,我们需要在用户点击按钮的时候,更新count
的状态值。React
提供了一个方法用来更新组件的state
,我们只需要在这些方法中,通过调用this.setState
,来更新状态就可以了:
increment = () => {
this.setState({
count: this.state.count + 1
})
}
decrement = () => {
this.setState({
count: this.state.count - 1
})
}
setState
方法接收一个对象作为参数,然后它会将这个对象合并到当前的state
中,从而达到更新的目的。这时,当我们再点击按钮时,可以看到页面就会自动更新了。以上操作就是state
的基本用法。
MVC
接下来我们再来了解一下React
中的状态管理机制。在前端的开发中,我们经常提到MVC
的概念,同时,很多前端框架也说自己是基于MVC
,那什么是MVC
呢?单从概念上理解,MVC
实际上指的是一种软件开发的设计思路,它将我们的代码,从组织的形式上,分成了3
个部分,分别是View
,Model
和Controller
,也就是视图,数据模型和控制器。
-
View
:视图,实际上指的就是用户操作界面。 -
Model
:数据模型,指的就是应用的内部数据,它可以是用户看到的数据,也可能是某些视图的显示状态,这些数据我们统统称之为应用的状态。 -
Controller
:控制器,指的就是整个应用的逻辑处理,比如用户的行为,数据的处理等等,我们常常把这一部分定义成方法,当成控制器来统一管理。
接下来,我们再来看看这三部分之间的关系,视图层View
是用来展示应用数据的,因此,我们将Model
中的数据交给View
,同时,在视图层中,还绑定了不同类型的事件等待用户触发,当用户触发某一类型的事件的时候,比如点击了某个按钮,这时,Controller
控制器中的方法被执行,在这些方法中,会涉及到不同业务的处理,处理完成之后,会去更新应用中的数据状态,当数据状态发生更新时,会通知其视图层进行更新。这时,用户就可以看到最新的数据了。从这种数据流的方式上我们可以发现,整个视图的显示,实际上就是依赖于应用中的Model
,当Model
一旦发生更新,View
也会随着它的更新而更新。
下面我们在来看一下,MVC
的这种设计思路,在React
框架中是如何体现的,回到刚刚计数器那个示例。
我们可以看到,在Counter
组件中:
-
state
相当于MVC
中的Model
,也就是整个应用的数据状态; -
increment
和decrement
这两个方法就是Controller
控制器,调用时更新state
; -
render
方法的返回值,就是应用的用户界面View
;
- 在页面初始化时,
render
方法被调用,同时返回整个页面的结构,ReactDOM
会根据这个结构来构建用户界面。渲染完成之后,页面进入到运行阶段,等待用户进行操作。 - 当用户触发某种事件时,组件内部的方法被调用,也就是
controller
被执行,这时,应用执行相应的业务处理,完成之后,调用setState
方法来更新当前的状态值。 - 当
state
完成更新之后,调用render
方法,获取到当前最新的页面结构。 - 更新
view
,用户就可以看到最新的页面了。
从以上的流程上我们可以知道,View
的展示,依赖于state
,当state
更新时,View
也会主动更新。在传统的方式中,当页面构建完成之后,如果需要更新页面中的某个数据时,我们首先需要拿到绑定了这个数据的节点,然后将新的数据更新到这个节点中,才能完成视图的更新。但是在react
中,我们不再需要考虑怎样去拿到节点,更新数据,而是直接修改state
状态即可,关于视图的更新,则交给react
自行完成,这样的方式,让我们从繁琐的节点操作中脱离出来,直接面向数据进行操作。