React useState更新滞后一步,调用setState后无法获取最新值如何解决?
问题本质
React中useState返回的更新函数是异步批量执行的,调用setLower后并不会立刻修改当前函数闭包中的lowerState值,更新后的state要等到下一次组件重渲染时才会生成。你在handleOnClick中访问的lowerState是本次组件渲染时的旧值,所以会出现更新滞后一步的现象,这是React的正常设计,并非BUG。
解决方案
方案1:直接使用已获取的最新值(最优)
你已经把input的最新处理结果存在变量x里了,所有需要用到最新值的场景直接调用x即可,完全不需要等待state更新:
const handleOnClick = () => { const x = document.getElementById("my_input").value.toLowerCase(); setLower(x) // 直接用x就可以拿到最新值 console.log(x) history.push('/test', {params : x}) };
方案2:用useEffect监听state变化
如果确实需要在state更新完成后执行后续逻辑,把对应逻辑放到监听lowerState的useEffect回调中即可,注意依赖项要补全:
import { useState, useEffect } from "react" // ...组件内代码 const [lowerState, setLower] = useState("") const history = useHistory(); useEffect(() => { // 可加判断过滤初始空值场景 if(lowerState) { console.log(lowerState) // 此处可拿到更新后的最新值 history.push('/test', {params : lowerState}) } }, [lowerState, history]) // 依赖项必须包含监听的state和用到的history const handleOnClick = () => { const x = document.getElementById("my_input").value.toLowerCase(); setLower(x) };
之前用useEffect无效大概率是依赖项填写不正确,或者没有过滤初始值触发的逻辑。
附加优化建议
不推荐用document.getElementById操作DOM拿input值,改为React受控组件写法更符合框架设计,也能避免DOM操作的潜在问题:
const [inputVal, setInputVal] = useState("") const [lowerState, setLower] = useState("") // 绑定input的onChange事件 const handleInputChange = (e) => { setInputVal(e.target.value) } const handleOnClick = () => { const x = inputVal.toLowerCase() setLower(x) history.push('/test', {params : x}) } // 渲染input时绑定value和onChange // <input value={inputVal} onChange={handleInputChange} id="my_input" />
内容的提问来源于stack exchange,提问作者GLHF
相关产品推荐
相关产品推荐

