React中API加载时禁用按钮,切换标签后仍保持禁用状态的实现方法
解决方案
该问题本质是请求库的窗口聚焦重请求特性导致的加载状态临时重置,当前的
disabled仅绑定了单次请求的isLoading状态,没有覆盖窗口失焦返回后的状态间隙。
方法1:直接关闭对应请求的窗口聚焦重校验特性
如果你不需要切回页面自动刷新数据,直接给你的APIpost请求配置关闭refetchOnWindowFocus即可,以React Query为例:
const APIpost = useMutation({ mutationFn: postData, // 新增这一行,关闭窗口聚焦时自动重请求 refetchOnWindowFocus: false, // 其他原有配置 })
改完后切回页面不会触发额外的重校验,isLoading状态就不会被意外重置。
方法2:额外加独立加载状态兜底(适合需要保留重校验特性的场景)
如果需要保留切页刷新数据的功能,就自己维护一个独立的加载状态,不受请求库的重校验逻辑影响:
import { useState } from 'react' // 组件内新增自定义加载状态 const [isBtnDisabled, setIsBtnDisabled] = useState(false) const APIpost = useMutation({ mutationFn: postData, onMutate: () => { // 请求发起时设置禁用 setIsBtnDisabled(true) }, onSettled: () => { // 请求不管成功失败都解除禁用 setIsBtnDisabled(false) } // 其他原有配置 }) // 按钮绑定两个状态兜底 return ( <Button disabled={APIpost.isLoading || isBtnDisabled} onClick={ () => APIpost.mutate(filter)} > )
这种方式下即使用户切页触发重校验,你自己维护的isBtnDisabled状态不会变,按钮会始终保持禁用直到请求真正结束。
方法3:绑定请求的isPending状态(React Query v5+适用)
如果你用的是React Query v5以上版本,isLoading仅指代首次发起请求的加载状态,isPending才包含所有请求(包括重校验、重试)的加载状态,直接把disabled绑定的值换成APIpost.isPending即可:
return ( <Button disabled={APIpost.isPending} onClick={ () => APIpost.mutate(filter)} > )
内容的提问来源于stack exchange,提问作者inconnu
相关产品推荐
相关产品推荐

