Why the fetchData
function is defined inside the useEffect
and not outside ?
Link: https://github.com/zeit/next.js/blob/canary/examples/with-graphql-faunadb/lib/useFetch.js
import { useState, useEffect } from 'react'
export default function useFetch(url, options) {
const [data, setData] = useState(null)
const [error, setError] = useState(null)
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(url, options)
const json = await res.json()
setData(json)
} catch (error) {
setError(error)
}
}
fetchData()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [url])
return { data, error }
}
I would have done that:
import { useState, useEffect } from 'react'
export default function useFetch(url, options) {
const [data, setData] = useState(null)
const [error, setError] = useState(null)
// Defined outside of useEffect
// `u` instead of `url` for not overlapping
// with the one passed in useFetch()
const fetchData = async (u) => {
try {
const res = await fetch(u, options)
const json = await res.json()
setData(json)
} catch (error)
setError(error)
}
}
useEffect(() => {
// Using url as an argument
fetchData(url)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [url])
return { data, error }
}
It seems easier to read and better organized. I'm thinking it's maybe an anti-pattern or something else ?
I typically define the functions inside the useEffect, there are several reasons for that
On that last one, for instance, you can do some actions to prevent state being called when the effect cleans up.
You could also use AbortController with fetch to cancel the fetch.
import { useState, useEffect } from 'react'
export default function useFetch(url, options) {
const [data, setData] = useState(null)
const [error, setError] = useState(null)
useEffect(() => {
let isUnmounted = false;
const fetchData = async () => {
try {
const res = await fetch(url, options)
const json = await res.json()
if(!isUnmounted) setData(json)
} catch (error) {
if(!isUnmounted) setError(error)
}
}
fetchData()
return ()=>{isUnmounted = true;}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [url])
return { data, error }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With