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 "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">
Book Name:
<input type="text" name="book" />
</label>
<button type="submit">Submit</button>
</form>
{results.isLoading ? (
<div>Loading...</div>
) : results.isError ? (
<div>{results.error.message}</div>
) : (
<div>
<h2>Results</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;
CodePudding user response:
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;
CodePudding user response:
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;