示例:等价的class组件
使用class实现一个计数器,你可能会这么写
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
复制代码
下面是使用Hook重构的代码
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
复制代码
Hooks和函数组件
Hook出来以前,函数组件和无状态组件是等价的,但是Hook出来以后,函数组件也可以有状态了,此时二者并不等价。所以我们现在更喜欢使用函数组件这个名字
Hook不能在class组件中使用
什么是Hook?
什么是Hook?Hook就是一个钩子函数,用Hook就能从函数组件里hook到React state和生命周期。比如useState就是一个Hook,它能让函数组件使用React state(原本只有class组件才有state的)
何时该使用Hook? 如果你在编写一个函数组件并意识到你需要为它添加一些状态,之前你必须将它转换为一个类。现在,您可以在现有函数组件中使用Hook。
声明状态变量
在class组件里我们通过在构造函数中将this.state设置为{count:0}来将计数状态初始化为0
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
复制代码
在function组件内部调用useState Hook
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
复制代码
useState 做了什么? useState声明了一个状态变量。
- 这里我们的变量叫做count,但我们可以称之为其他任何东西,比如banana。
- useState是一种在函数调用之间“保留”某些值的方法。通常,当函数退出时变量会被清除,但React将保留状态变量。
- useState和this.state提供了完全相同的功能。
传递给useState作为参数是什么? useState的唯一参数是初始状态。
- 与类不同,状态不必是对象。可以是任何类型的值
- 在我们的示例中,我们只需要一个数字表示用户单击的次数,因此将0作为变量的初始状态。
- 如果我们想在状态中存储两个不同的值,我们可以调用useState两次。
useState返回什么? 当前状态和更新它的函数。
- 这与类中的this.state.count和this.setState类似,只不过将它们放在一对中。
为什么useState没有命名为createState?
"create"不准确,因为状态仅在我们的组件第一次呈现时create。下一次渲染useState将为我们“提供”当前状态。否则它根本不会是“状态”! Hook名称总是已以"use"开头也是有原因的。我们将在后来的规则中了解原因。
读取状态
类组件里我们这么写
<p>You clicked {this.state.count} times</p>
复制代码
函数组件里我们这么写
<p>You clicked {count} times</p>
复制代码
更新状态
类组件:
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
复制代码
In a function, we already have setCount
and count
as variables so we don’t need this
:
<button onClick={() => setCount(count + 1)}>
Click me
</button>
复制代码