I created a custom hook.
It makes a fetch request from a api, gets the result as expected.
It has a function called "fetchMore" which is used to fetch the data based on its previous values.
I have two problems with this:
- 1: When the function fetchMore is called from inside the component, if I log the current state inside the hook it just logs an empty object, that way I can't use the previous state to fetch the next results.
- 2: When the function fetchMore is called from inside the component, the setData which requests new data returns a pending promise as the new state for the component.
Question: do you guys have any idea how I could make this "fetchMore" work?
Component:
import { useCallback, useState } from 'react'
import logo from './images/webpack.png'
import { useFetch } from './hooks/useFetch'
export const App = () => {
const [count, setCount] = useState(0)
const [data, fetchMore] = useFetch()
const { results } = data
console.log(" ~ file: App.jsx ~ line 8 ~ App ~ data", data)
const incrementCount = useCallback(async () => {
setCount((prev) => prev + 1)
await fetchMore()
}, [fetchMore, data])
return (
<div className='wrapper'>
<header className='header'>
<h1>React app! {count}</h1>
<button className='increment' onClick={incrementCount}>+</button>
</header>
<section>
<a href='https://webpack.js.org/'>
<img className='logo' src={logo} alt="Webpack5" width={200} />
</a>
{results?.map((r) => <p key={r.name}>{r.name}</p>)}
</section>
</div>
)
}
Hook:
import { useEffect, useState, useCallback } from "react"
const fetchPokemons = async (url) => {
const res = await fetch(url ?? 'https://pokeapi.co/api/v2/pokemon')
return await res.json()
}
export const useFetch = () => {
const [data, setData] = useState({})
const setList = useCallback(async () => {
const res = await fetchPokemons()
setData(res)
}, [])
const fetchMore = useCallback(async () => {
console.log(" ~ file: useFetch.jsx ~ line 10 ~ useFetch ~ data", data)
setData(async (prev) => {
const res = await fetchPokemons(prev.next)
const newState = {...prev, ...res, results: [...prev.results, ...res.results]}
return newState
})
}, [])
useEffect(() => {
setList()
return () => {
setData({})
}
}, [setList])
return [data, fetchMore]
}