useEffect runs only once and after refresh it does not fetch again

I have this component that fetches data from a site, and tries to get its keys.
The problem is that it works fine at the first time, but when I refresh the page / save the project in VSCode (and the project refreshes automatically) it shows this error message:

TypeError: Cannot convert undefined or null to object
  14 |    )
  15 | 
  16 |    return (
> 17 |        <div className="rates">
     | ^  18 |            {Object.keys(rates.rates).map(
  19 |                rate => <Button variant="outlined">
  20 |                    {rate}

The code (the specific component):

import React, { useState, useEffect } from 'react'
import Button from '@mui/material/Button';


const RatesCard = () => {

    const [rates, setRates] = useState([]);
    useEffect(
        ()=>{
            fetch("https://api.vatcomply.com/rates")
            .then(ratesResponse => ratesResponse.json())
            .then(rates => setRates(rates));
        }
    ,[])

    return (
        <div className="rates">
            {Object.keys(rates.rates).map(
                rate => <Button variant="outlined">
                    {rate}
                </Button>
            )}
        </div>
        )
    }
    

export default RatesCard

I have no idea why it works the first time and then it doesn’t. My guess is that the useEffect hook runs only once because of the [] dependency, and then when we refresh it says “Nothing changed, so I won’t run the function” Thus we don’t fetch anything, and thus rates is undefined

I have no clue why it does this, I can only guess. I will appreciate your kind help! Thank you!

Answer

useEffect runs after your component is mounted which means rates is just an empty array that doesn’t have a property called rates

Object.keys(rates.rates)

try to use

const [rates, setRates] = useState({rates:[]});

or make a loading indicator for example

const RatesCard = () => {

    const [rates, setRates] = useState([]);
    useEffect(
        ()=>{
            fetch("https://api.vatcomply.com/rates")
            .then(ratesResponse => ratesResponse.json())
            .then(rates => setRates(rates));
        }
    ,[])


    if(rates.length === 0) {
        return <h1> loading </hi>
     }
    return (
        <div className="rates">
            {Object.keys(rates.rates).map(
                rate => <Button variant="outlined">
                    {rate}
                </Button>
            )}
        </div>
        )