useQuery Hook 的结果集显示为 loading,而没有被调用。

huangapple go评论84阅读模式
英文:

useQuery Hook result set to loading without being called

问题

这是您的翻译:

我正在尝试在我的新项目中构建一个搜索栏,似乎有一些(也许很多)错误。

我将书籍状态设置为null,useQuery钩子似乎正在使用它来搜索书籍。

除非我点击按钮,否则我不希望它搜索任何东西。

以下是我的代码:

fetchBooks.jsx

```jsx
async function fetchBooks({ queryKey }) {
  const book = queryKey[1];

  const response = await fetch(
    `https://www.googleapis.com/books/v1/volumes?q=${book}`
  );
  if (!response.ok) {
    throw new Error(`未找到关于${book}的搜索结果`);
  }
  return response.json();
}

export default fetchBooks;

这是主要组件。

import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import fetchBooks from "../helper/fetchBooks";

const Home = () => {

    const [book, setBook] = useState(null);

    const results = useQuery(["search", book], fetchBooks);

    const handleSubmit = (e) => {
        e.preventDefault();
        setBook(e.target.elements.book.value);
    };

    return (
        <>
            <form onSubmit={handleSubmit}>
                <label htmlFor="book">
                    书名
                    <input type="text" name="book" />
                </label>
                <button type="submit">提交</button>
            </form>

            {results.isLoading ? (
                <div>加载中...</div>
            ) : results.isError ? (
                <div>{results.error.message}</div>
            ) : (
                <div>
                    <h2>搜索结果</h2>
                    <ul>
                        {results.data.items.map((item) => {
                            return (
                                <div key={item.id}>
                                    <h3>{item.volumeInfo.title}</h3>
                                    <p>{item.volumeInfo.authors}</p>
                                </div>
                            );
                        })}
                    </ul>
                </div>
            )}
        </>
    );
};

export default Home;
英文:

I'm trying to build a search bar in my new project, and I seem to be doing some things(maybe a lot) wrong.

I set the book state to null and the useQuery hook seems to be using it to search for books.

I don't want it to search for anything unless I click the button.

These are my codes:

fetchBooks.jsx

async function fetchBooks({ queryKey }) {
  const book = queryKey[1];

  const response = await fetch(
    `https://www.googleapis.com/books/v1/volumes?q=${book}`
  );
  if (!response.ok) {
    throw new Error(`Search not found for ${book}`);
  }
  return response.json();
}

export default fetchBooks;

Here is the main component.

import { useState } from &quot;react&quot;;
import { useQuery } from &quot;@tanstack/react-query&quot;;
import fetchBooks from &quot;../helper/fetchBooks&quot;;

const Home = () =&gt; {

    const [book, setBook] = useState(null);

    const results = useQuery([&quot;search&quot;, book], fetchBooks);

    const handleSubmit = (e) =&gt; {
        e.preventDefault();
        setBook(e.target.elements.book.value);
    };

    return (
        &lt;&gt;
            &lt;form onSubmit={handleSubmit}&gt;
                &lt;label htmlFor=&quot;book&quot;&gt;
                    Book Name:
                    &lt;input type=&quot;text&quot; name=&quot;book&quot; /&gt;
                &lt;/label&gt;
                &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
            &lt;/form&gt;

            {results.isLoading ? (
                &lt;div&gt;Loading...&lt;/div&gt;
            ) : results.isError ? (
                &lt;div&gt;{results.error.message}&lt;/div&gt;
            ) : (
                &lt;div&gt;
                    &lt;h2&gt;Results&lt;/h2&gt;
                    &lt;ul&gt;
                        {results.data.items.map((item) =&gt; {
                            return (
                                &lt;div key={item.id}&gt;
                                    &lt;h3&gt;{item.volumeInfo.title}&lt;/h3&gt;
                                    &lt;p&gt;{item.volumeInfo.authors}&lt;/p&gt;
                                &lt;/div&gt;
                            );
                        })}
                    &lt;/ul&gt;
                &lt;/div&gt;
            )}
        &lt;/&gt;
    );
};

export default Home;


答案1

得分: 1

你可以在 fetch 函数中如果 book 为 null,则返回一个默认值。这样,查询实际上不会请求 API。

async function fetchBooks({ queryKey }) {
  const book = queryKey[1];

  if (!book) return { items: [] }

  const response = await fetch(
    `https://www.googleapis.com/books/v1/volumes?q=${book}`
  );
  if (!response.ok) {
    throw new Error(`Search not found for ${book}`);
  }
  return response.json();
}

export default fetchBooks;
英文:

You can return a default value in the fetch function if the book is null. Then, the query won't actually request the API.

async function fetchBooks({ queryKey }) {
  const book = queryKey[1];

  if(!book) return { items: [] }

  const response = await fetch(
    `https://www.googleapis.com/books/v1/volumes?q=${book}`
  );
  if (!response.ok) {
    throw new Error(`Search not found for ${book}`);
  }
  return response.json();
}

export default fetchBooks;

答案2

得分: 0

以下是翻译好的部分:

"Instead of restricting the useQuery to call the fetchBooks functions, you can modify the fetchBooks functions to return an empty array if book is set to null. The fetchBooks can be modified as below:"

"不必将useQuery限制为调用fetchBooks函数,可以修改fetchBooks函数以在book设置为null时返回一个空数组。可以按照以下方式修改fetchBooks:"

async function fetchBooks({ queryKey }) {
  const book = queryKey[1];
  if (!book) {
    return { 
      isLoading: false,
      error: null,
      data: null
    }
  }
  const response = await fetch(
    `https://www.googleapis.com/books/v1/volumes?q=${book}`
  );
  if (!response.ok) {
    throw new Error(`Search not found for ${book}`);
  }
  return response.json();
}

export default fetchBooks;
英文:

Instead of restricting the useQuery to call the fecthBooks functions, you can modify the fetchBooks functions to return an empty array if book is set to null. The fetchBooks can be modified as below:-

async function fetchBooks({ queryKey }) {
  const book = queryKey[1];
  if(!book){
    return { 
              isLoading : false,
              error : null,
              data : null
           }
  }
  const response = await fetch(
    `https://www.googleapis.com/books/v1/volumes?q=${book}`
  );
  if (!response.ok) {
    throw new Error(`Search not found for ${book}`);
  }
  return response.json();
}

export default fetchBooks;

答案3

得分: 0

使用惯用方式是在参数未准备好时将 useQuery 本身设置为 disabled(通过 enabled 属性):

const results = useQuery({
  queryKey: ["search", book],
  queryFn: fetchBooks,
  enabled: !!books
})

这将在没有书籍时阻止查询函数的执行。

英文:

The idiomatic way would be to set the useQuery itself to disabled (via the enabled property) when your params aren't ready:

const results = useQuery({
  queryKey: [&quot;search&quot;, book],
  queryFn: fetchBooks
  enabled: !!books
})

this will prevent the query function from executing when you have no books.

huangapple
  • 本文由 发表于 2023年1月6日 15:05:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75027938.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定