首页 > 解决方案 > React 查询突变现在确实会使用相同的输入再次触发

问题描述

当我尝试使用该useMutation钩子进行 POST API 调用时,它第一次以正确的响应(成功或错误)工作。如果这是一个错误,如果我用与以前相同的数据重试突变,什么也不会发生。如果我使用不同的数据,它会重新发送 POST 请求。

这是我的用例:我有一个文件输入。用户上传文件,使用 POST API 通过 POST API 发送文件,useMutation发生错误。现在,如果我作为用户尝试重新上传相同的文件,则不会发生任何事情。但如果用不同的文件重新上传,API 会再次发送。

这是我的input代码:

    const [newAvatarFile, setNewAvatarFile] = useState<File>(null);
    const { isSuccess, error, isLoading, mutate } = useMutation(updateUserAvatar);

    useEffect(() => {
      newAvatarFile && mutate(newAvatarFile);
    }, [newAvatarFile, mutate]);

    return (
      <input
        type="file"
        accept={'image/*'}
        onChange={(e: ChangeEvent<HTMLInputElement>) => {
          setNewAvatarFile(e.target.files[0]);
        }}
      /> 
    )

这是我的 API 调用函数updateUserAvatar

    import { AxiosError, AxiosResponse } from 'axios';
    import { Axios } from '../axios-instance';

    export const updateUserAvatar = async (data: File): Promise<Record<string, string>> => {
      let result: AxiosResponse;

      try {
        result = await Axios.post(
          '/some/api/url',
           { profile_picture: data },
           {
             headers: {
               'Content-Type': 'multipart/form-data',
           },
        }
      );
    } catch (err) {
      const error = err as AxiosError;
      throw new Error(
        error.response ? error.response.data.message || error.response.data : error.message
      );
    }

    return result.data;
  };

标签: reactjsfile-iomutationreact-query

解决方案


我只能猜测效果没有运行是因为文件被认为是相同的?您是否可以在 onChange 处理程序中运行突变:

    const [newAvatarFile, setNewAvatarFile] = useState<File>(null);
    const { isSuccess, error, isLoading, mutate } = useMutation(updateUserAvatar);

    return (
      <input
        type="file"
        accept={'image/*'}
        onChange={(e: ChangeEvent<HTMLInputElement>) => {
          setNewAvatarFile(e.target.files[0]);
          mutate(e.target.files[0])
        }}
      /> 
    )

我认为这更明确,如果你只需要它来实现效果,也许你甚至可以摆脱newAvatarFile状态,留下:

    const { isSuccess, error, isLoading, mutate } = useMutation(updateUserAvatar);

    return (
      <input
        type="file"
        accept={'image/*'}
        onChange={(e: ChangeEvent<HTMLInputElement>) => {
          mutate(e.target.files[0])
        }}
      /> 
    )

推荐阅读