Warm tip: This article is reproduced from serverfault.com, please click

next.js-React-Query useQuery发送无限获取请求

(next.js - React-Query useQuery sending infinite fetch requests)

发布于 2020-12-26 22:30:57

当我按以下方式使用useQuery时,按照在react-query文档中使用的方式,它会发送无限数量的获取请求。该文档还说,获取不会自动引发错误。因此,我在下面尝试了相同的代码,但使用try-catch块使用了getAlbums。我还尝试在useQuery挂钩中的对象中配置staleTime,但是它没有用,我真的不知道什么是过时时间。哈哈。请帮帮我。想在星期一之前完成这个项目

在我的控制台中发现此错误:

(node:27609) UnhandledPromiseRejectionWarning: ReferenceError: navigator is not defined
    at OnlineManager.isOnline (/Users/benridesbikes/repos/photo_album/node_modules/react-query/lib/core/onlineManager.js:64:5)
    at /Users/benridesbikes/repos/photo_album/node_modules/react-query/lib/core/retryer.js:142:86
(Use `node --trace-warnings ...` to show where the warning was created)
(node:27609) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:27609) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
import React from "react";
import { useQuery, useMutation, useQueryClient } from "react-query";
import Link from "next/link";
import Form from "../../components/styles/Form";
import Container from "../../components/styles/AlbumsIndex";
import Button from "../../components/styles/Button";

async function getAlbums() {
  const response = await fetch(`api/albums/`);
  const { albums } = await response.json();
  return albums;
}

async function createAlbum(newAlbum) {
  const response = await fetch(`/api/albums/create`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(newAlbum),
  });
  const { album } = await response.json();
  return album;
}

async function deleteAlbum(albumId) {
  await fetch(`/api/albums/delete`, {
    method: "DELETE",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(albumId),
  });
}

export default function Index() {
  const queryClient = useQueryClient();

  const refetchQuery = async () => {
    await queryClient.refetchQueries();
  };

  const { data: albums, error } = useQuery("albums", getAlbums);

  const mutationCreateAlbum = useMutation(createAlbum, {
    onSuccess: refetchQuery(),
  });

  const mutationDeleteAlbum = useMutation(deleteAlbum, {
    onSuccess: refetchQuery(),
  });

  const [formData, setFormData] = React.useState({
    name: "",
    description: "",
  });

  const handleChange = (event) => {
    setFormData({ ...formData, [event.target.name]: event.target.value });
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    mutationCreateAlbum.mutate({
      name: formData.name,
      description: formData.description,
    });
    setFormData({
      name: "",
      description: "",
    });
  };

  const useDeleteMutation = (albumId) => {
    mutationDeleteAlbum.mutate({
      id: albumId,
    });
  };

  return (
    <Container>
      <Form>
        <h1>Create a New Album</h1>
        <label htmlFor="name">
          Name:
          <input
            type="text"
            id="name"
            name="name"
            value={formData.name}
            onChange={handleChange}
            placeholder="Give Your Album a Name!"
          />
        </label>
        <label htmlFor="description">
          Description:
          <input
            type="text"
            id="description"
            name="description"
            value={formData.description}
            onChange={handleChange}
            placeholder="Give Your Album a Description!"
          />
        </label>
        <Button onClick={(event) => handleSubmit(event)}>
          Make New Album!
        </Button>
      </Form>
      <div className="albums">
        {albums &&
          albums.map((album) => (
            <div className="album" key={album.id}>
              <Link href={`/albums/${album.id}`}>
                <a>
                  <Button>{album.name}</Button>
                </a>
              </Link>
              <h3>{album.description}</h3>
              <Button onClick={() => useDeleteMutation(album.id)}>
                Delete
              </Button>
            </div>
          ))}
      </div>
    </Container>
  );
}
Questioner
Benjamin Higginbotham
Viewed
0
Benjamin Higginbotham 2020-12-27 08:44:25

解决了!IDK确切说明了此解决方案有效的原因。我有一个预感,它与钩子和React重新渲染有关。简而言之,函数:

 const refetchQuery = async () => {
    await queryClient.refetchQueries();
  };

是不断重复发送提取内容的原因。解决方案是删除此函数,而是在onSuccess之后调用“ queryClient.refetchQueries()”作为异步函数,如下所示:

  const queryClient = useQueryClient();

  const { data: albums, error } = useQuery("albums", getAlbums);

  const mutationCreateAlbum = useMutation(createAlbum, {
    onSuccess: async () => await queryClient.refetchQueries(),
  });

  const mutationDeleteAlbum = useMutation(deleteAlbum, {
    onSuccess: async () => await queryClient.refetchQueries(),
  });