2
\$\begingroup\$

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

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Welcome to Code Review! We need to know what the code is intended to achieve. To help reviewers give you better answers, please add sufficient context to your question, including a title that summarises the purpose of the code. We want to know why much more than how. The more you tell us about what your code is for, the easier it will be for reviewers to help you. The title needs an edit to simply state the task, rather than your concerns about the code. \$\endgroup\$ Jul 3 '21 at 7:44
  • 1
    \$\begingroup\$ Thank you, Toby, I tried to be more clear now 😊 \$\endgroup\$
    – Ton
    Jul 4 '21 at 12:57
  • 1
    \$\begingroup\$ To make code less messy you can add a base object that implements basic call, then extend it with specific calls and after that use it within other features. \$\endgroup\$ Jul 4 '21 at 20:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.