Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

286
Views
¿Cómo obtener datos de un gancho React personalizado (API) con onClick y mostrarlos en un Div usando TypeScript?

Soy nuevo en TypeScript e incluso en React Hooks. Estoy tratando de obtener datos continuamente de un gancho personalizado llamado useFetch() , que toma un parámetro de cadena (la URL):

 import { useEffect, useState } from "react"; export interface Payload { data: null | string, loading: boolean } const useFetch = (url: string) => { const [state, setState] = useState<Payload>({data: null, loading: true}) useEffect(() => { setState(state => ({ data: state.data, loading: true })); fetch(url) .then(x => x.text()) .then(y => { setState({ data: y, loading: false }); }); }, [url, setState]) return state; } export default useFetch;

Importo ese gancho en App() :

 import React, { useState, useEffect } from "react"; import useFetch from './utils/useFetch' import {Payload} from './utils/useFetch'; const App = () => { const [quote, setquote] = useState<Payload>({data: null, loading: true}) const handleClick = () => setquote(data) const data = useFetch( "/api/rand" ); return ( <div> <h1>Quotes</h1> <button onClick={handleClick}>Get Quote</button> <div>{quote.data}</div> </div> ) } export default App;

La primera vez que carga la aplicación, funciona. Obtengo datos (una cotización) cuando hago clic en el botón.

Avance

Sin embargo, cuando hago clic en él varias veces, no se vuelve a llamar a la API y no aparecen nuevos datos. Creo que se supone que debo usar el gancho de reacción useEffect() y mantener el estado (tal vez me equivoque), pero todos mis intentos hasta ahora han sido en vano. Cualquier ayuda sería muy apreciada. Si lo descubro, definitivamente responderé esta pregunta. ¡Gracias!

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Parece que estás mezclando dos ideas un poco aquí.

¿Quieres obtener datos de forma continua? (Continuamente significa todo el tiempo, como en, periódicamente, en un intervalo)

¿O desea obtener datos sobre el montaje del componente (actualmente sucede) Y cuando el usuario toca el botón "Obtener cotización" (no funciona actualmente)?

Intentaré ayudarte con las dos.

Continuamente/periódicamente

Prueba a cambiar un poco la configuración. Dentro de useFetch haz algo como:

 import { useEffect, useState } from "react"; export interface Payload { data: null | string, loading: boolean } const useFetch = (url: string) => { const [state, setState] = useState<Payload>({data: null, loading: true}) useEffect(() => { const interval = setInterval(() => { setState(state => ({ data: state.data, loading: true })); fetch(url) .then(x => x.text()) .then(y => { setState({ data: y, loading: false }); }); }, 2000); // Something like 2s return () => { clearInterval(interval); // clear the interval when component unmounts } }, [url]) return state; } export default useFetch;

Esto buscará el punto final cada 2 segundos y actualizará la variable de estado, esto luego se reflejará en la aplicación (o en cualquier lugar que use el enlace).

Por lo tanto, ya no necesita el estado de cotización en la aplicación. Además, ya no necesita un botón en la interfaz de usuario.

La aplicación se verá algo como:

 import React, { useState, useEffect } from "react"; import useFetch from './utils/useFetch' import {Payload} from './utils/useFetch'; const App = () => { const quote = useFetch( "/api/rand" ); return ( <div> <h1>Quotes</h1> <div>{quote.data}</div> </div> ) } export default App;

Obtener datos al montar el componente (actualmente sucede) Y cuando el usuario presiona el botón "Obtener cotización"

Entonces, en mi opinión, el gancho useFetch no es realmente necesario/adecuado. Se puede usar un enlace para esta aplicación, pero transformarlo en una función más simple tendría más sentido para mí. Sugiero omitir el gancho useFetch. El componente de la aplicación se vería así:

 import React, { useState, useEffect, useCallback } from "react"; const App = () => { const [quote, setQuote] = useState<Payload>({data: null, loading: true}) const handleGetQuote = useCallback(() => { setQuote(state => ({ data: state.data, loading: true })); fetch("/api/rand") .then(x => x.text()) .then(y => { setQuote({ data: y, loading: false }); }); }, []); useEffect(() => { handleGetQuote(); }, [handleGetQuote]); return ( <div> <h1>Quotes</h1> <button onClick={handleGetQuote}>Get Quote</button> <div>{quote.data}</div> </div> ) } export default App;
about 4 years ago · Juan Pablo Isaza Report

0

Aquí hay otra posibilidad: agregué una función de recarga a los valores de retorno de useFetch . Además, dado que el useFetch ya contiene su propio estado, useState de la App

 const useFetch = (url: string) => { const [state, setState] = useState<Payload>({data: null, loading: true}) const [reloadFlag, setReloadFlag] = useState(0) useEffect(() => { if(reloadFlag !== 0){ // remove this if you want the hook to fetch data initially, not just after reload has been clicked setState(state => ({ data: state.data, loading: true })); fetch(url) .then(x => x.text()) .then(y => { setState({ data: y, loading: false }); }); } }, [url, setState, reloadFlag]) return [state, ()=>setReloadFlag((curFlag)=>curFlag + 1)]; } const App = () => { const [data, reload] = useFetch( "/api/rand" ); return ( <div> <h1>Quotes</h1> <button onClick={reload}>Get Quote</button> <div>{quote.data}</div> </div> ) }
about 4 years ago · Juan Pablo Isaza Report

0

Simplemente cambie el código de la siguiente manera:

 const useFetch = (url: string) => { const [state, setState] = useState<Payload>({data: null, loading: true}) setState(state => ({ data: state.data, loading: true })); fetch(url) .then(x => x.text()) .then(y => { setState({ data: y, loading: false }); }); return state; } export default useFetch;
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!