React Native - Expo 中useState存储选中项缺失最后一次操作的问题
问题根因
- React 中
useState的更新是异步批量执行的,调用setSelected后,当前函数作用域内的selected变量仍是本次函数触发时的旧值,不会实时更新为最新值,因此你调用updateUser时传入的始终是本次操作前的旧数组,才会出现操作滞后一次的现象。 - 原有逻辑存在分支漏洞:当
selected为undefined时,执行完setSelected([item])后没有终止后续判断,还会继续执行下方的if-else分支,触发重复更新甚至引发报错。
修复代码
// 初始化直接给定空数组作为默认值,消除undefined判断逻辑 const [selected, setSelected] = React.useState<string[]>([]) React.useEffect(() => { const getBrands = async () => { const user = await getUser() // 兜底空数组,避免赋值undefined setSelected(user?.brands ?? []) } getBrands() }, []) const toggleSelection = async(item: string) => { console.log("clicked: ", item) // 提前计算出更新后的最新数组,不依赖state的异步更新结果 const newSelected = selected.includes(item) ? selected.filter(i => i !== item) : [...selected, item] setSelected(newSelected) // 直接传入提前计算好的最新值调用接口 await updateUser({brands: newSelected}) }
补充说明
如果后续遇到需要依赖上一次state值做更新的场景,也可以使用setSelected的函数式更新写法:setSelected(prev => prev.includes(item) ? prev.filter(i => i !== item) : [...prev, item]),这种写法拿到的prev参数永远是最新的state值,不会出现闭包捕获旧值的问题。
内容的提问来源于stack exchange,提问作者user3359670
相关产品推荐
相关产品推荐

