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

React-query:POST请求后实现数据重获取的更优方案

React组件层级

组件层级图

首页组件使用react-query获取数据,子组件UserForm执行POST请求提交数据。目前我通过props传递refetch方法,在POST请求完成后重新获取服务器数据,请问有没有更优的实现方式?

首页组件代码

export default function HomePage() {
  const {
    isLoading,
    isFetching,
    isError,
    refetch,
    data: users,
  } = useQuery(['users'], getUsers);

  if (isLoading) {
    return <h1>loading..!!!</h1>;
  }

  if (isError) {
    return <h1>error</h1>;
  }

  return (
    <div>
      <UserForm refetch={refetch} />
      <ul>
        {users.length ? (
          users?.map((user: IUser) => <UserItem key={user.id} user={user}  refetch={refetch}/>)
        ) : (
          <li>data error</li>
        )}
      </ul>
    </div>
  );
}

UserForm组件提交函数

const handleSubmitAddUser = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (name) {
      addUser(name)
        .then(() => {
          setName('');
          refetch();
        })
        .catch((err) => console.error(err));
    }
  };

更优实现方式:用react-query的useMutation结合缓存失效

不用手动传递refetch,借助react-query的缓存管理机制自动更新数据,具体实现如下:

1. 在UserForm中替换为useMutation

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useState } from 'react';

const UserForm = () => {
  const queryClient = useQueryClient();
  const [name, setName] = useState('');

  // 用useMutation包裹新增用户逻辑
  const addUserMutation = useMutation({
    mutationFn: (userName) => addUser(userName),
    onSuccess: () => {
      setName('');
      // 标记'users'查询缓存失效,react-query会自动重新拉取数据
      queryClient.invalidateQueries({ queryKey: ['users'] });
    },
    onError: (err) => console.error(err)
  });

  const handleSubmitAddUser = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (name) {
      addUserMutation.mutate(name);
    }
  };

  // 组件其余渲染逻辑...
};

2. 首页组件移除refetch传递

export default function HomePage() {
  const {
    isLoading,
    isFetching,
    isError,
    data: users,
  } = useQuery(['users'], getUsers);

  if (isLoading) {
    return <h1>loading..!!!</h1>;
  }

  if (isError) {
    return <h1>error</h1>;
  }

  return (
    <div>
      <UserForm /> {/* 无需传递refetch */}
      <ul>
        {users.length ? (
          users?.map((user: IUser) => <UserItem key={user.id} user={user} />) {/* 也不用传refetch */}
        ) : (
          <li>data error</li>
        )}
      </ul>
    </div>
  );
}

优势说明

  • 组件解耦:子组件不再依赖父组件的refetch方法,降低耦合度
  • 自动缓存管理:react-query接管缓存失效和重新请求逻辑,不用手动调用refetch
  • 扩展性强:后续其他组件修改用户数据时,只需调用invalidateQueries(['users'])就能统一更新数据

如果addUser接口会返回新增的用户数据,还可以直接更新缓存避免额外请求,效率更高:

onSuccess: (newUser) => {
  setName('');
  // 直接更新缓存数据,跳过网络请求
  queryClient.setQueryData(['users'], (oldUsers) => {
    return [...(oldUsers || []), newUser];
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:20:40