React component not persisting custom hook state

Viewed 41

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]
}
0 Answers
Related