Tengo este componente que obtiene datos de un sitio e intenta obtener sus claves.
El problema es que funciona bien la primera vez, pero cuando actualizo la página/guardo el proyecto en VSCode (y el proyecto se actualiza automáticamente) muestra este mensaje de error:
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}
El código (el componente específico):
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
No tengo ni idea de por qué funciona la primera vez y luego no. Supongo que el useEffect
se ejecuta solo una vez debido a la dependencia []
, y luego, cuando actualizamos, dice "Nada cambió, así que no ejecutaré la función". Por lo tanto, no obtenemos nada y, por lo tanto, rates
no están undefined
. ...
No tengo idea de por qué hace esto, solo puedo adivinar. ¡Agradeceré su amable ayuda! ¡Gracias!
useEffect
se ejecuta después de montar su componente, lo que significa que rates
son solo una matriz vacía que no tiene una propiedad llamada rates
Object.keys(rates.rates)
tratar de usar
const [rates, setRates] = useState({rates:[]});
o hacer un indicador de carga por ejemplo
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> )
Su valor predeterminado para las tasas debe ser un objeto vacío con la propiedad de rates
establecida en una matriz vacía ( {rates: []}
).
Al decir las siguientes Object.keys(rates.rates).map
, asume que las rates
serán un objeto, y rates.rates
será una matriz.
Funciona la "primera" vez debido a cómo funciona la recarga en caliente, porque cuando guarda sus archivos, inyecta códigos en el navegador y no vuelve a montar toda la aplicación. Por lo tanto, su aplicación continuará desde donde se quedó antes, incluso si se bloqueó en la carga anterior.
Cambie su definición de estado a lo siguiente: const [rates, setRates] = useState({rates:[]});
Esto asegurará que cuando su aplicación intente ejecutar Object.keys(rates.rates).map
no se bloquee porque tiene una matriz para iterar no null
/ undefined