React 18中的state概念与使用、注意问题解决
作者:_七七
一、概念与基本使用
props中的所有属性都是不可变的,这使得React组件不能随着props的改变而改变。但在实际的开发中,我们更希望的是数据发生变化时,页面也会随着数据一起变化。React为我们提供了state用来解决这个问题。
state和props类似,都是一种存储属性的方式,但是不同点在于state只属于当前组件,其他组件无法访问。并且state是可变的,当其发生变化后组件会自动重新渲染,以使变化在页面中呈现。
在React中,当组件渲染完毕后,再修改组件中的变量,不会使组件重新渲染。
要使得组件可以收到变量的影响,必须在变量修改后对组件进行重新渲染。
这里我们就需要一个特殊变量,当这个变量被修改时,组件会自动重新渲染。
state相当于一个变量,
只是这个变量在React中进行了注册,
React会监控这个变量的变化,当state发生变化时,会自动触发组件的重新渲染
使得我们的修改可以在页面中呈现出来。
在函数组件中,我们需要通过钩子函数,获取state。
使用钩子 useState()
来创建state。
import {useState} from "react";
它需要一个值作为参数,这个值就是state的初始值
该函数会返回一个数组
- 数组中第一个元素,是初始值
- 初始值只用来显示数据,直接修改不会触发组件的重新渲染数组中的第二个元素,是一个函数,通常会命名为setXxx
- 这个函数用来修改state,调用其修改state后会触发组件的重新渲染,并且使用函数中的值作为新的state值
现有如下组件Clock:
现在我们希望点击按钮以后,时间可以刷新直接显示一个当前的最新日期。希望页面重新渲染。但是,如果直接在clickHandler中修改date的值是无效的,像这样:
在函数中使用state我们需要使用一种钩子(hook)函数。钩子函数可以在函数组件中“勾出”React的特性,换句话说我们要用一个函数“勾出”state。
语法:
const [state, setState] = useState(initialState);
通过钩子函数useState()勾出state,useState()中需要传递一个初始值,这个值就是你希望在变量中存储的值。
函数会返回一个数组,数组中有两个元素,第一个元素是存储了值的变量,第二个元素是一个函数用来对值进行修改。
比如上边的案例,可以这样修改:
使用useState()“勾出”的变量就是一个普通变量,它里边存储了初始化的值,这个变量和其他变量没什么大区别,同样修改这个变量的值也不会对组件产生实质性的影响,所以不要尝试直接为state赋值。useState()“勾出”的函数用来修改state的值,他需要一个新的state值作为参数,调用后会触发组件的重新渲染,从而使得页面刷新,在每次的重新渲染中都会使用新的state值作为参数。
二、注意问题
引出问题
有了state,使得React组件可以随着某个值的改变而改变,我们无需再在某个值发生变化后重新手动对界面进行构建,React会替我们完成这些工作,大大降低了我们开发的难度。
但是state中还隐藏着一些不太容易发现的问题,现在假设我们需要开发一个计数器组件,这个组件非常简单,有一个按钮和一个数字,每点击一次按钮数字就会增加1,大概长成这个样子:
点击按钮以后,数字就会增加1,这个组件的实现很简单:
Counter.js
在clickHandler()中,我们调用了setCount(count+1)来对count进行更新,每次更新都是在前一次值的基础上增加1。这个代码这么写在大部分的场景下都不会带来任何的问题,但是在某些情况下就不一定了。
产生问题的原因
在React中我们通过setState()修改状态都是异步完成的,换句话说并不是调用完setState()后状态立刻就发生变化,而是需要等上一段时间,当然这段时间不会很长。
像上边的案例中state的修改虽然是异步完成的,但是由于功能比较简单,等待时间几乎可以忽略不计。但随着功能复杂度的提升,这个间隔会逐渐增多。
问题演示
假设调用setState()后1秒state的值才会真的改变,这时如果我们连续点击按钮2次,第1次点击按钮时count值是1,第2次点击速度比较快,从而两次间隔没有超过1秒,此时的count值依然是1,这就导致我点击了两次按钮,但是值只增加了1次,因为两次count+1中的count都是1。
为了演示问题,可以将上述案例的setCount()放入到一个延时调用中:
这样一来,点击按钮后1秒setCount()才会调用,如果我们在1秒内点击按钮多次,你会发现按钮数值只会增加一次,很显然我们不希望这种情况出现。
解决问题
要解决这个问题,其实也不难,在setState()时除了直接传递一个指定值以外,React还允许我们通过一个回调函数来修改state,回调函数的返回值就是新的state的值,使用回调函数的好处是,这个回调函数会确保上一次的setState()调用完成后才被调用,同时会使用最新的state值作为回调函数的第一个参数。这样一来就有效的避免了无法正确获取上一个state值的问题。
上边案例中的 setCount(count+1);
可以改成这个样子:
setCount(prevState => prevState+1);
这样一来,函数中的prevState总是上次修改后的最新state,避免再次出现点击多次按钮只修改一次的问题。总的来说,当我们修改一个state的值而需要依赖于前边的值进行计算时,最安全的方式就是通过回调函数而不是直接修改。
到此这篇关于React 18中的state概念与使用、注意问题的文章就介绍到这了,更多相关React state概念与使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!