在之前的react版本中要往组件中添加状态要用类组件才可以,在新的react版本中加入了hooks使得函数组件也具备了添加状态的功能而且使用上也非常的方便。
在类组件中定义状态用state定义,但是修改状态必须要用到setState来修改,为了更好的感知性能,React 会延迟调用setState,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效,我们测试一下:
class Count extends React.Component{
state = {
count: 1
}
handlecount = () => {
this.setState({count: this.state.count+1})
console.log("点击button " + this.state.count)
}
render(){
return(
<div>
<div>{this.state.count}</div>
<button onClick={this.handlecount}>add count</button>
</div>
)
}
}
我在页面中定义了一个类组件并且添加状态赋予初始值1,添加一个button点击事件让count+1然后直接输出查看结果
![](https://img.haomeiwen.com/i19445607/fd6e8f5a44a0adf8.png)
页面已经变为了2,控制台还是1,如果我们开发时需要拿到最新的值做下面的处理,这样显然会出现问题。不过setState还给我们提供了第二个参数接收一个函数修改代码如下:
class Count extends React.Component{
state = {
count: 1
}
handlecount = () => {
this.setState({count: this.state.count+1}, () => console.log("点击button " + this.state.count))
}
render(){
return(
<div>
<div>{this.state.count}</div>
<button onClick={this.handlecount}>add count</button>
</div>
)
}
}
点击button查看效果
![](https://img.haomeiwen.com/i19445607/2f66acfc6a080f34.png)
这次拿到了最新的值。
接下来用类组件和函数组件使用useState写两个小demo看看结果有什么不同;首先实现类组件:
class Count extends React.Component{
state = {
count: 1
}
handleClick = () => {
setTimeout(() => alert(this.state.count), 2000)
}
handlecount = () => {
this.setState({count: this.state.count+1})
}
render(){
return(
<div>
<div>{this.state.count}</div>
<button onClick={this.handleClick}>提交</button>
<button onClick={this.handlecount}>add count</button>
</div>
)
}
}
我重写了Count组件,新加了一个提交的按钮,给他添加了一个点击方法,用定时器控制2s后弹出count。我们进行这样的操作,点击提交后,快速点击add count按钮,等弹窗弹出查看count的值。显示如下:
![](https://img.haomeiwen.com/i19445607/31d88c0fa63abfd3.png)
弹出的值与页面一致,说明取到了最新的值。接下来再写一个函数组件做一样的操作,代码如下:
import React, {useState} from "react"
function Hooksdemo (){
const [count, setCount] = useState(0);
function handleClick (){
setTimeout(() => alert(count), 2000)
}
function handlecount (){
setCount(count+1)
}
return (
<div>
<div>{count}</div>
<button onClick={handleClick}>提交</button>
<button onClick={handlecount}>add count</button>
</div>
)
}
export default Hooksdemo
需要引入useState,和上面一样操作页面查看弹窗效果
![](https://img.haomeiwen.com/i19445607/9317650280b94b8c.png)
发现和上面结果是不一样的。现在我们修改代码以达到上面的效果,引入useRef。修改如下
function Hooksdemo (){
const [count, setCount] = useState(0);
const uref = useRef();
uref.current = count;
function handleClick (){
setTimeout(() => alert(uref.current), 2000)
}
function handlecount (){
setCount(count+1)
}
return (
<div>
<div>{count}</div>
<button onClick={handleClick}>提交</button>
<button onClick={handlecount}>add count</button>
</div>
)
}
export default Hooksdemo
![](https://img.haomeiwen.com/i19445607/b784d16c475564bf.png)
![](https://img.haomeiwen.com/i19445607/3ed1b37e4bc34e06.png)
第一张图是输出的useRef(),发现他有一个current属性,我们把count的值赋给了他,最后弹出uref.current。结果和之前一样了,useRef页面重新渲染并不会创建一个新的对象,所以把值赋予current的属性改变的还是刚创建时的对象。
网友评论