React中useState在onChange绑定函数内更新后首次取值为空如何解决
问题原因
React 中 useState 返回的状态更新函数是异步批量执行的,调用 setTag(val) 后不会立刻修改当前函数作用域内的 tag 变量,当前渲染周期的 tag 仍然是闭包缓存的旧值,所以你在 setTag 后立刻读取 tag 拿到的是更新前的值,导致请求参数错误。
解决方法
方法1:直接使用入参 val 发起请求(最简便)
调用 handleTagSearch 时你已经拿到了输入框的最新值,不需要依赖状态里的 tag 构造请求,直接使用入参即可:
const [ tag, setTag ] = useState(''); const [ tags, setTags ] = useState([]); const handleTagSearch = async(val) => { console.log("target val: ", val); setTag(val); // 直接使用传入的最新val构造请求地址 const url = '127.0.0.1:8000/api/tag?name=' + val; const resp = await axios.get(url); // ...后续逻辑 }; return ( <div> <input type="text" name="tags" value={tag} onChange={e=>handleTagSearch(e.target.value)} /> </div> );
方法2:用 useEffect 监听 tag 变化触发请求
如果你的请求逻辑除了 tag 还依赖其他状态,或者需要等 tag 真正更新后再执行后续操作,可以把请求逻辑放到 useEffect 中,监听 tag 的变化自动触发请求:
const [ tag, setTag ] = useState(''); const [ tags, setTags ] = useState([]); // tag变化时自动执行请求逻辑 useEffect(() => { // 可选:输入为空时跳过请求 if (!tag) return; const fetchTags = async () => { console.log("value of tag: ", tag); const url = '127.0.0.1:8000/api/tag?name=' + tag; const resp = await axios.get(url); // ...后续更新tags等逻辑 }; fetchTags(); }, [tag]); // 依赖项为tag,tag每次更新都会触发effect执行 const handleTagSearch = (val) => { console.log("target val: ", val); setTag(val); }; return ( <div> <input type="text" name="tags" value={tag} onChange={e=>handleTagSearch(e.target.value)} /> </div> );
如果输入频率高可以额外加防抖逻辑,避免短时间发起大量无效请求。
内容的提问来源于stack exchange,提问作者forest
相关产品推荐
相关产品推荐

