React点击按钮后控制台输出值总是滞后一步的问题求助
问题:React状态更新滞后,控制台打印总是慢一步
我有三个对象数组,想在控制台打印它们。点击其他组件的按钮时会切换对应的数组,但现在打印结果总是滞后一步:
关联关系
- Arr1(3个对象)→ 对应btn1
- Arr2(6个对象)→ 对应btn2
- Arr3(2个对象)→ 对应btn3
预期效果
- 点击btn1 → 打印包含3个对象的数组
- 点击btn2 → 打印包含6个对象的数组
- 点击btn3 → 打印包含2个对象的数组
实际表现
- 点击btn1 → 打印
[] - 点击btn2 → 打印Arr1的3个对象
- 点击btn3 → 打印Arr2的6个对象
- 再次点击btn1 → 打印Arr3的2个对象
- 再次点击btn2 → 打印Arr1的3个对象
代码
// 这三个变量是传入的props getKpiResolvedTix, getKpiCanceledTix, getKpiClosedTix const [newKpiTixArr, setNewKpiTixArr] = useState<any>([]) const renderCsvData = () => { if (getKpiResolvedTix) { setNewKpiTixArr(getKpiResolvedTix) } else if (getKpiCanceledTix) { setNewKpiTixArr(getKpiCanceledTix) } else if (getKpiClosedTix) { setNewKpiTixArr(getKpiClosedTix) } } useEffect(() => { renderCsvData() console.log(newKpiTixArr) }, [getKpiResolvedTix, getKpiCanceledTix, getKpiClosedTix])
代码说明
这三个get开头的变量都是props,点击按钮时会筛选工单,只返回对应状态的工单数组:
- 点击“已解决”按钮 → 返回
getKpiResolvedTix数组 - 点击“已取消”按钮 → 返回
getKpiCanceledTix数组 - 点击“已关闭”按钮 → 返回
getKpiClosedTix数组
原因与解决方法
原因
React的setState是异步操作,调用setNewKpiTixArr后,newKpiTixArr不会立刻更新。你在useEffect里调用renderCsvData后直接打印newKpiTixArr,此时拿到的还是更新前的旧值,所以会出现滞后。
解决方法
方法1:直接打印目标值,无需等待状态更新
既然已经明确要设置的数组是哪个,直接打印对应的props即可,不用依赖状态:
useEffect(() => { let targetArr = [] if (getKpiResolvedTix) { targetArr = getKpiResolvedTix setNewKpiTixArr(targetArr) } else if (getKpiCanceledTix) { targetArr = getKpiCanceledTix setNewKpiTixArr(targetArr) } else if (getKpiClosedTix) { targetArr = getKpiClosedTix setNewKpiTixArr(targetArr) } console.log(targetArr) }, [getKpiResolvedTix, getKpiCanceledTix, getKpiClosedTix])
方法2:监听状态变化,更新后再打印
新增一个专门监听newKpiTixArr的useEffect,等状态更新完成后再打印:
const renderCsvData = () => { if (getKpiResolvedTix) { setNewKpiTixArr(getKpiResolvedTix) } else if (getKpiCanceledTix) { setNewKpiTixArr(getKpiCanceledTix) } else if (getKpiClosedTix) { setNewKpiTixArr(getKpiClosedTix) } } useEffect(() => { renderCsvData() }, [getKpiResolvedTix, getKpiCanceledTix, getKpiClosedTix]) // 监听状态更新,打印最新值 useEffect(() => { console.log(newKpiTixArr) }, [newKpiTixArr])
方法3:简化逻辑,去掉不必要的状态
如果newKpiTixArr只是用来中转props的值,完全可以直接使用props,不用额外维护状态:
// 移除不必要的useState定义 // const [newKpiTixArr, setNewKpiTixArr] = useState<any>([]) useEffect(() => { let targetArr = [] if (getKpiResolvedTix) { targetArr = getKpiResolvedTix } else if (getKpiCanceledTix) { targetArr = getKpiCanceledTix } else if (getKpiClosedTix) { targetArr = getKpiClosedTix } console.log(targetArr) }, [getKpiResolvedTix, getKpiCanceledTix, getKpiClosedTix])
内容的提问来源于stack exchange,提问作者some_new_dev_dude
相关产品推荐
相关产品推荐

