I'm trying to query data from an api by passing it a breed and a sub-breed as arguments. I'm storing these values as state and updating them on button click.
Does anyone know how to query the data only AFTER the state has been updated? Because otherwise the arguments would be undefined and I'd get an error.
I tried putting the hook inside the handleClick function but I got an error telling me it was an invalid hook call.
Any ideas?
import React, { useState, useRef } from "react";
import {
useGetAllDogsQuery,
useGetImageByBreedQuery,
} from "../features/api/apiSlice";
import { Button, ImageList } from "@mui/material";
import { TextField } from "@mui/material";
import { Box, ImageListItem } from "@mui/material";
const SpecificBreed = () => {
const inputRef = useRef("");
const inputRef2 = useRef("");
const [dogInfo, setDogInfo] = useState({
subBreed: "",
breed: "",
});
const { data, isSuccess } = useGetImageByBreedQuery(
dogInfo.breed,
dogInfo.subBreed
);
let images = [];
function handleClick() {
setDogInfo({
subBreed: inputRef2.current,
breed: inputRef.current.replace(/\s/g, ""),
});
}
function handleChange(event) {
inputRef.current = event.target.value;
}
function handleChange2(event) {
inputRef2.current = event.target.value;
console.log(inputRef2);
}
if (isSuccess) {
let arrayCopy = {
...data.message,
};
Object.values(arrayCopy).map((image) => {
if (image) {
images.push(
<ImageListItem
key={
image.includes("(")
? image.substring(0, image.length - 5) +
image.substring(image.length - 4, image.length)
: image
}
cols={Math.floor(Math.random() * 2) + 2}
rows={Math.floor(Math.random() * 2) + 2}
sx={{
"&.MuiImageListItem-root": {
border: `2px solid black`,
},
}}
>
<img
src={image.includes("xeshaBelka") ? "" : image}
alt="dog"
loading="lazy"
/>
</ImageListItem>
);
}
});
}
return (
<Box
width="100%"
display="flex"
justifyContent="center"
marginTop="350px"
flexDirection="column"
gap="5rem"
alignItems="center"
sx={{}}
>
<Box
width="50%"
display="flex"
justifyContent="center"
alignItems="center"
flexDirection="column"
gap="20px"
>
<TextField
variant="outlined"
label="Enter a breed..."
sx={{ width: "100%" }}
inputRef={inputRef}
onChange={(event) => handleChange(event)}
/>
<TextField
variant="outlined"
label="Enter a sub-breed..."
sx={{ width: "100%" }}
inputRef={inputRef2}
onChange={(event) => handleChange2(event)}
/>
<Button
variant="contained"
sx={{ width: "100%" }}
onClick={handleClick}
>
Find Pictures
</Button>
</Box>
<ImageList variant="masonry" cols={4} gap={8} sx={{ p: "1rem" }}>
{images}
</ImageList>
</Box>
);
};
export default SpecificBreed;
The API's running fine, I tried it with hard-coded values but here it is:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const apiSlice = createApi({
reducerPath: "api",
baseQuery: fetchBaseQuery({
baseUrl: "https://dog.ceo/api/",
}),
tagTypes: ["Dogs"],
endpoints: (builder) => ({
getAllDogs: builder.query({
query: () => `breeds/list/all`,
// providesTags: (result) =>
// result ? result.map(({ id }) => ({ type: "Dogs", id })) : [],
}),
getRandomImage: builder.query({
query: (number) => `breeds/image/random/${number}`,
}),
getImageByBreed: builder.query({
query: ({ breed, subBreed }) =>
`breed/${breed}/${subBreed}/images/random`,
}),
}),
});
export const {
useGetAllDogsQuery,
useGetRandomImageQuery,
useGetImageByBreedQuery,
} = apiSlice;