【safari】react在safari浏览器中,遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。如何解决

在safari浏览器中,可能会遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。

PS:由于useState是一个普通的函数, 定义为() => void;因此此处不能用await/async替代setTimeout,只能用在返回值为Promise时

有问题的代码:

我们可以看到,setTimeout只传0,这个时候在谷歌浏览器是有效果的,能确保顺序正确,但是在safari浏览器下,obj的值没有办法及时更新上state。

typescript 复制代码
const columnsChange = ({ key, val }: { key: string | number; val: any }) => {
        const obj = {
            [key]: Array.isArray(val) && val?.length > 0 ? val : undefined
        };
        setFilters((f) => ({ ...f, ...obj }));
        setPagination({ pageNo: 1, pageSize: PAGE_SIZE });
        setTimeout(() => {
            run();
        }, 0);
    };

修改后的代码:

于是,我们尝试使用await/async去处理异步,但是由于setState是一个普通的函数, 定义为() => void;因此此处不能用await/async替代setTimeout,只能用在返回值为Promise时。因此不能这样做!

typescript 复制代码
const columnsChange = async ({ key, val }: { key: string | number; val: any }) => {
        const obj = {
            [key]: Array.isArray(val) && val?.length > 0 ? val : undefined
        };
        // 由于setState是一个普通的函数, 定义为() => void;因此此处不能用await/async替代setTimeout,只能用在返回值为Promise时
        await setFilters((f) => ({ ...f, ...obj }));
        setPagination({ pageNo: 1, pageSize: PAGE_SIZE });
        run();
    };
验证:我们通过查看useState的定义,查看Dispatch、SetStateAction的定义,可以看到都是() => void或者返回泛型S(这意味着如果我们要变更的状态不是promise,也不适用await写法)



正确的代码:

将异步时间微调大一些200ms

typescript 复制代码
const columnsChange = ({ key, val }: { key: string | number; val: any }) => {
        const obj = {
            [key]: Array.isArray(val) && val?.length > 0 ? val : undefined
        };
        // 由于setState是一个普通的函数, 定义为() => void;因此此处不能用await/async替代setTimeout,只能用在返回值为Promise时
        setFilters((f) => ({ ...f, ...obj }));
        setPagination({ pageNo: 1, pageSize: PAGE_SIZE });
        setTimeout(() => {
            run();
        }, 200);
    };
相关推荐
老陈聊架构几秒前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill
Ulyanov33 分钟前
从桌面到云端:构建Web三维战场指挥系统
开发语言·前端·python·tkinter·pyvista·gui开发
cypking1 小时前
二、前端Java后端对比指南
java·开发语言·前端
糠帅傅蓝烧牛肉面1 小时前
单实例多MCP聚合服务:两种实现方案深度对比
前端·docker·ai
JosieBook1 小时前
【Vue】12 Vue技术—— Vue 事件修饰符详解:掌握事件处理的高级技巧
前端·javascript·vue.js
艾斯特_2 小时前
Echarts常用配置项及解释
前端·javascript·echarts
m0_502724952 小时前
飞书真机调试
开发语言·前端·javascript
我只会写Bug啊3 小时前
复制可用!纯前端基于 Geolocation API 实现经纬度获取与地图可视化
前端·高德地图·地图·百度地图·经纬度
刘一说3 小时前
Vue3 模块语法革命:移除过滤器(Filters)的深度解析与迁移指南
前端·vue.js·js
lkbhua莱克瓦244 小时前
JavaScript核心语法
开发语言·前端·javascript·笔记·html·ecmascript·javaweb