Reputation: 1
Im creating a side project for fun in react with create-react-app. I created a hook thats supposed to fetch some information in json and it does the job, the problem is that for some reason its sending a request per item in the json and this is a json with 700+ items, is it a re-render situation? Is it because I'm not using useEffect?
export const useFetchQL = (url: URL): Array<Object> => {
const [data, setData] = useState([]);
const getData = async () => {
let query = `
query {
characters{
id
name
title
imageURL
leaderSkill
passive
categories
links
}
}`;
let response = await fetch(url,{
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({query}),
})
let data = await response.json();
setData(data.data.characters)
}
getData();
return data;
}
I tried calling it in different parts of the project and nothing, same output. What's happening here and how do I avoid it?
I only need/want to fetch this information once so I can start using it. I would like to post IMG but I cant.
import './App.css';
import Cards from './components/Cards';
import Team from './components/Team';
import Search from './components/Search';
import { AddToTeamProvider } from './context/addToTeamContext';
import { useState } from 'react';
import { useFetchQL } from './hooks/useFetchQL.ts';
function App() {
const [chars, setChars] = useState([]);
setChars(useFetchQL('https://dokkanapi.azurewebsites.net/graphql'));
console.log(chars);
return (
<div className="App">
<AddToTeamProvider>
<Team/>
<Search/>
<Cards/>
</AddToTeamProvider>
</div>
);
}
export default App;
Upvotes: 0
Views: 512
Reputation: 8332
First of all this is not the way you should write hook and use them. This is more a regular function that returns data after API is finished. You tried to combine API hook pattern with regular function.
Also you are calling it in the main render flow and it will call it many times since you are setting state every time component rerenders.
Here is the one example how you can do this:
export const getQL = async (url: URL): Array<Object> => {
let query = `
query {
characters{
id
name
title
imageURL
leaderSkill
passive
categories
links
}
}`;
let response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({ query }),
});
return response.json();
};
And than use this method in a useEffect
in your component:
import "./App.css";
import Cards from "./components/Cards";
import Team from "./components/Team";
import Search from "./components/Search";
import { AddToTeamProvider } from "./context/addToTeamContext";
import { useState } from "react";
import { getQL } from "./hooks/useFetchQL.ts";
function App() {
const [chars, setChars] = useState([]);
useEffect(() => {
const call = async () => {
const result = await getQL("https://dokkanapi.azurewebsites.net/graphql");
setChars(result);
};
call();
}, []);
return (
<div className="App">
<AddToTeamProvider>
<Team />
<Search />
<Cards />
</AddToTeamProvider>
</div>
);
}
export default App;
Upvotes: 3