Intento crear una aplicación simple que genere cotizaciones aleatorias. Creé una función que (creo) obtiene los datos que quiero del archivo json. Pero cuando trato de pasar esa función a la función de mi aplicación, obtengo un error: los objetos no son válidos como un niño React (encontrado: [promesa de objeto])
cita de la función:
function Quote (data) { var x = (Math.floor(Math.random() * (103 - 1) + 1) ); return fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json') .then((response) => response.json()) .then((responseJson) => { console.log(responseJson['quotes'][0]['author']); return responseJson['quotes'][x]['author']; }) .catch((error) => { console.error(error); }); }Función de la aplicación:
function App() { var text = ''; return ( <div id="quote-box"> <div id="author"><Quote /></div> <button id="new-quote">New Quote</button> <a href="twitter.com" id="tweet-quote">Tweet</a> </div> ); }Usaría useEffect para activar una llamada al principio. Y use useState para guardar el valor. Y luego también agregue la misma lógica al onClick.
import { useEffect, useState } from "react"; function getQuote() { var x = Math.floor(Math.random() * (103 - 1) + 1); return fetch( "https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json" ) .then((response) => response.json()) .then((responseJson) => { console.log(responseJson["quotes"][0]["author"]); return responseJson["quotes"][x]["author"]; }) .catch((error) => { console.error(error); }); } export default function App() { const [author, setAuthor] = useState(""); useEffect(() => { getQuote().then((newAuthor) => setAuthor(newAuthor)); }, []); return ( <div id="quote-box"> <div id="author">{author}</div> <button id="new-quote" onClick={() => getQuote().then((newAuthor) => setAuthor(newAuthor))} > New Quote </button> <a href="twitter.com" id="tweet-quote"> Tweet </a> </div> ) }También puede archivar de esta manera. Crea un gancho personalizado y utilízalo.
import React from "react"; function useFetchQuote(newQuote) { const [author, setAuthor] = React.useState(); React.useEffect(() => { var x = Math.floor(Math.random() * (20 - 1) + 1); return fetch( "https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json" ) .then((response) => response.json()) .then((responseJson) => { console.log(responseJson["quotes"][x]["author"]); setAuthor(responseJson["quotes"][x]["author"]); }) .catch((error) => { console.error(error); }); }, [newQuote]); return { author }; } function App() { const [newQuote, setQuote] = React.useState(0); const { author } = useFetchQuote(newQuote); return ( <div id="quote-box"> <div id="author">{author}</div> <button id="new-quote" onClick={() => setQuote(newQuote + 1)}> New Quote </button> <a href="twitter.com" id="tweet-quote"> Tweet </a> </div> ); } export default App;Devolver una promesa en los componentes de React no funcionará como lo que está haciendo en su código. Los componentes de React deben devolver un jsx . Por ejemplo, en un archivo llamado Quote.js
import * as React from 'react'; const url = 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json'; const Qoute = () => { const [quote, setQuote] = React.useState(null); React.useEffect(() => { fetch(url) .then((response) => response.json()) .then((data) => { const randomNumber = 1; // Generate random number which is lesser or equal to data's length setQuote(data['quotes'][randomNumber]); }); }, []); if (!quote) return <React.Fragment>Loading...</React.Fragment>; return <div>{JSON.stringify(quote)}</div>; }; export default Qoute;Luego, solo necesita importarlo en algún lugar donde le gustaría usarlo e invocarlo así
<Quote /> PD: Convertí esto de typescript si algo no funciona, estaré encantado de ayudar. Y recuerde actualizar la línea donde coloco un comentario. Buena suerte hermano.