You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中使用SWR如何在react-modal关闭时重校验数据

问题修复方案

核心原因:关闭react-modal时不会触发SWR默认的焦点重校验逻辑,需要手动调用SWR提供的mutate方法主动触发数据拉取,同时修复现有代码里的循环依赖bug。


步骤1:修正父组件SWR调用与副作用逻辑

首先从useSWR的返回值里解构出mutate方法,同时修复useEffect的依赖问题(原有依赖数组包含users会触发无限重渲染):

const { data, error, isValidating, mutate } = useSWR(
  process.env.NEXT_PUBLIC_APP_URL + `/api/users`,
  fetcher,
  {
    revalidateIfStale: true,
    revalidateOnFocus: true,
    revalidateOnMount:true, 
  }
);

useEffect(() => {
  if (data) {
    setUsers(data.users);
  }
}, [data]); // 移除依赖里的isValidating、users,避免死循环

// 加载、错误处理逻辑保持不变

return (
  <main className="mx-auto max-w-7xl ">
    <Header title="All users"/>
    <UsersList users={users} />
  </main>
);

步骤2:给弹窗组件传入操作完成回调

渲染用户列表时,把重校验方法作为回调传给DisableModal,另外注意你原有代码里users.((user)是语法笔误,缺少map方法:

const usersList = users.map((user) => (
  <div className="space-x-5 text-sm" key={user.id}>
    {user.name}
    <DisableModal 
      id={user.id} 
      isDisabled={user.active}
      onSuccess={() => mutate()} // 操作成功后触发SWR重校验
    />
  </div>
));

步骤3:弹窗组件内执行完禁用逻辑后触发回调

修改DisableModal组件,接收回调参数,等禁用接口请求成功、关闭弹窗后调用回调刷新列表:

export const DisableModal = ({
  id,
  isDisabled,
  onSuccess
}) => {
  const [disableModalIsOpen, setDisableModalIsOpen] = useState(false);

  function closeDisableModal() {
    setDisableModalIsOpen(false);
  }

  function openPublishModal() {
    setDisableModalIsOpen(true);
  }

  const handleDisableUser = async () => {
    // 等待禁用用户的接口请求执行完成
    // await 你的禁用接口调用逻辑
    await fetch(`/api/users/${id}/status`, {
      method: 'PATCH',
      body: JSON.stringify({ active: false })
    })
    
    closeDisableModal();
    // 触发父组件传入的重校验逻辑
    onSuccess?.();
  }

  // 其余弹窗渲染逻辑保持不变
}

可选优化:避免层层传参

如果不想通过props逐层传递mutate方法,可以直接在弹窗组件里用SWR提供的全局配置钩子拿到mutate,不需要父组件传参:

import { useSWRConfig } from 'swr';

export const DisableModal = ({ id, isDisabled }) => {
  const { mutate } = useSWRConfig();
  const [disableModalIsOpen, setDisableModalIsOpen] = useState(false);

  // 其余逻辑不变
  const handleDisableUser = async () => {
    // 执行禁用接口逻辑
    await fetch(/* 你的接口地址 */)
    closeDisableModal();
    // 精准重校验用户列表接口
    mutate(process.env.NEXT_PUBLIC_APP_URL + `/api/users`);
  }
}

注意:调用mutate时传入对应接口的key作为参数,只会重校验该接口的缓存,性能比全局重校验更好。

内容的提问来源于stack exchange,提问作者wick3d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:33:17