Estoy aprendiendo React y estaba tratando de desarrollar un código para obtener 10 números aleatorios con datos interesantes correspondientes de una API "Números API".
el problema al que me enfrento es que, cuando ejecuto el código, aparece un error
"Error: los objetos no son válidos como elementos secundarios de React (encontrado: [promesa de objeto]). Si pretendía representar una colección de elementos secundarios, use una matriz en su lugar"
a continuación he adjuntado el código:
const originalArray = new Array(10).fill(0); const mappedArray = originalArray.map((n, index) => Math.floor(Math.random() * 100) ); console.log("mappedArray", mappedArray); console.log("joined array string", mappedArray.join(",")); async function callApi(numbers) { const fetchResponse = await fetch(`http://numbersapi.com/${numbers}/math`); if (fetchResponse.ok) { const data = await fetchResponse.json(); console.log("all good, heres the response", data); } else console.log("There was a problem"); } const Number = async() => { const [add, setAdd] = React.useState([]); // <-- valid initial empty state React.useEffect(() => { callApi(mappedArray). then(values => setAdd(values)); }, []); // <-- invoke on component mount <div className="container"> {add.map((newlist, i) => ( <div className="item" key={i}> {newlist} </div> ))} </div> ); export default Number;¿Puede alguien ayudarme a solucionar este problema? Gracias
Necesitas mantener el estado . React es muy particular con su ciclo de vida. Así que aquí tengo un estado data y una función, setData , que lo actualiza.
Para los componentes de la función React, usamos useEffect , esencialmente el antiguo componentDidMount de los componentes de la clase, para cargar datos cuando el componente se monta por primera vez. Luego podemos establecer el estado con esos datos que ahora sabemos que son una matriz de objetos.
Una vez que el estado se actualiza, el componente se vuelve a renderizar. Luego puede iterar sobre Object.entries usando la clave para la clave y el valor como fuente de texto.
function Number() { // Initialise the state with an empty array const [data, setData] = useState([]); // Separate out the function that creates the number array function createNumbers() { const originalArray = new Array(10).fill(0); return originalArray.map(() => Math.floor(Math.random() * 100)).join(''); } useEffect(() => { async function getNumbers() { try { const res = await fetch(`http://numbersapi.com/${createNumbers()}/math`); const data = await res.json(); // Set the new component state using the data setData(data); } catch (err) { console.log(err); } } getNumbers(); }, []); return ( <div className="container"> {Object.entries(data).map(([key, value]) => ( <div className="item" key={key}> {value} </div> ))} </div> ); }; export default Number;Eso es porque su función de add todavía devuelve una Promise ya que es una función async
Todavía tendrá que await a que se add al final, luego utilícelo:
Algo como esto:
const Number = async () => { const data = await add; <div className="container"> {data.map((newlist, i) => ( <div className="item" key={i}> {newlist} </div> ))} </div>; };callApi es async , por lo que implícitamente devuelve una Promesa, que guardas en add e intentas representar. Este es el objeto del que se queja React.
Querrá invocar esta función dentro del ciclo de vida del componente React y guardar el resultado en el estado que se va a representar.
const Number = () => { const [add, setAdd] = React.useState([]); // <-- valid initial empty state React.useEffect(() => { callApi(mappedArray). then(values => setAdd(values)); }, []); // <-- invoke on component mount return ( <div className="container"> {add.map((newlist, i) => ( <div className="item" key={i}> {newlist} </div> ))} </div> ); }; Cuando envía una lista de números separados por comas a este numbersapi , devuelve un objeto JSON que no se puede representar como una matriz.
El formato de respuesta siempre será un mapa JSON de números a hechos, de 100 números como máximo.
Ejemplo de respuesta a http://numbersapi.com/53,65,70/math
{ "53": "53 is the 16thprime number.", "65": "65 is the 23rdsemiprime and the 3rd of the form (5.q)it is an octagonal number.", "70": "70 is the smallest weird number." }Parece que desea guardar los valores en el estado:
React.useEffect(() => { callApi(mappedArray). then(result => setAdd(Object.values(result))); }, []);O puede obtener la matriz de valores al renderizar:
return ( <div className="container"> {Object.values(add).map((newlist, i) => ( <div className="item" key={i}> {newlist} </div> ))} </div> ); Si desea tanto la clave como el valor, use Object.entries para obtener una matriz de matrices de pares de valores clave.
Ejemplo:
[ ['53', '53 is the 16thprime number.'], ['65', '65 is the 23rdsemiprime and the 3rd of the form (5.q)it is an octagonal number.'], ['70', '70 is the smallest weird number.'], ] return ( <div className="container"> {Object.entries(add).map(([key, value], i) => ( <div className="item" key={key}> {key}: {value} </div> ))} </div> );