I'm trying to separate the fetch logic from the component, but, due to the nature of async/await functions I have to write an async function to call other async function and I wanted to know if that's ok, if it decreases performance and what are the good practices on this.
Here's an example of a fetch function in the postEvent.js file and then used in the page.js, a page component.
//postEvent.js
const postEvent = async newEvent => {
try {
const csrf = await getCsrf()
const apiEnd = "http://localhost:8000/events/";
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": csrf,
},
credentials: "include",
body: JSON.stringify(newEvent),
};
const response = await fetch(apiEnd, options); //1st await
return {ok: response.ok, json: await response.json()} //2nd await
} catch (e) {return e;}
}
//page.js
const response = await postEvent(newEvent) //3rd await
response.ok && Router.push(`/events/${response.json.slug}`)
I could avoid the 3rd await if I put all the code in the same file, but it gets too messy, does the number of awaits matter?
I've been looking it up and came to another approach, where I can make a useFetch function and share the state instead of returning a promise, like so:
//useFetch.js
const useEvent = async newEvent => {
const [data, setData] = useState()
useEffect(async () => ({
try {
const csrf = await getCsrf()
const apiEnd = "http://localhost:8000/events/";
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": csrf,
},
credentials: "include",
body: JSON.stringify(newEvent),
}
const response = await fetch(apiEnd, options);
setData(await response.json())
} catch (e) {return e;}
},[newEvent])
return data
}
//page.js
const data = useEvent(newEvent) //3rd await
Router.push(`/events/${data.slug}`)
I guess the second way is better than the first, but I still don't understand the need of useEffect if I'm only going to call it once for event