useState
react中一般使用useState方法为,初始化值为second,设置first的方法为setfirst。
const [first, setfirst] = useState(second)
一般情况下使用不会有什么问题,但是在你刚设置完状态后不能立刻使用该状态,原因是setState是异步执行的,何为异步执行?javascript为单线程,意思是只能自上而下顺序执行,如果某一环节出现问题,之后的也不会执行,所以javascript引入了异步执行操作。
js异步执行机制:
首先判断该任务是同步还是异步,同步进入主线程顺序执行,异步的进入Event table
异步任务在Event table中注册函数,然后被推入Event queue
当主线程执行完所有的同步任务空闲之后,才去Event queue中查看是否有可执行的异步任务,如果有,就推入到主线程中执行
由于setState是异步的,所以下面这段代码点击重置后不会立刻获得默认列表,但是第二次点击会获得默认列表,显然这是不符合预期的,所以应该怎么解决呢?
const fun = () => {
const [first, setfirst] = useState(second)
//页面加载时,获取列表并展示
useEffect(() => {
getList()
} , [])
//搜索就是通过传入不同参数获得不同的结果列表
const getList = () => {
//发送请求,获取数据展现到页面上
.......
}
//重置按钮就是将输入框置为空,然后获取默认列表
const reset = () => {
setfirst('')
getList()
}
return (
<React.Fragment>
<div>
<input type = "text" value = "{first}"/>
<button onclick = {getList}>搜索</button>
<button onclick = {reset}>重置</button>
</div>
</React.Fragment>
)
}
useRef
- 上述的问题可以通过useRef来解决,使用方式如下,这种方式就可以实现点击reset后,清空输入框的值,并获取默认列表展示。
const fun = () => { |
两者区别
- 受控组件与非受控组件
- 受控组件:类似于useState这种,将组件的值放入state中进行维护,所以要访问组件的值,直接在state中进行读取,不必获取对应组件了,设置组件的值也要通过setState进行设置,整个过程就是组件的状态与维护。
- 非受控组件:react本身并没有维护组件的值,想要获取组件的值,通过ref获取组件,然后通过ref获取或者设置组件的值,随取随用,且设置值后立即生效。
- 由于useRef设置值是同步的,所以会立即生效。
问题记录
- 在使用antd的Input输入框组件,通过useRef获取和设置组件的值,获取值的方式:first.current.input.value,设置值的方式:first.current.input.value = ‘’,类似于上面的例子,使用antd的input框点击重置后,有一瞬间清空了input,但是马上又恢复了之前input框输入的值,检查之后,感觉代码没什么问题,可能是antd的BUG吧。
总结
- 遇到问题:就是想点击reset后,清空输入框,并发送请求,展示默认的列表,
- 刚开始使用受控组件useState,但是由于是异步更改状态的,所以不行
- 后来使用非受控组件useRef,但是由于使用的antd,会有bug,也不行,如果使用html原生的,就没有问题
- 最后先使用受控组件:useState,input绑定的是useState的值,定义一个非受控组件useRef,使用useEffect,监测useState的值,当他的值改变,就将他的值赋给useRef所定义的那个变量。在发送请求的getList函数中读取useRef所定义的值即可。