• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

264
Views
React Hook Warnings para la función asíncrona en useEffect: la función useEffect debe devolver una función de limpieza o nada

Estaba probando el ejemplo de useEffect algo como a continuación:

 useEffect(async () => { try { const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`); const json = await response.json(); setPosts(json.data.children.map(it => it.data)); } catch (e) { console.error(e); } }, []);

y recibo esta advertencia en mi consola. Pero creo que la limpieza es opcional para las llamadas asíncronas. No estoy seguro de por qué recibo esta advertencia. Vinculación de sandbox para ejemplos. https://codesandbox.io/s/24rj871r0p ingrese la descripción de la imagen aquí

about 3 years ago · Santiago Trujillo
3 answers
Answer question

0

Sugiero mirar la respuesta de Dan Abramov (uno de los mantenedores del núcleo de React) aquí :

Creo que lo estás complicando más de lo necesario.

 function Example() { const [data, dataSet] = useState<any>(null) useEffect(() => { async function fetchMyAPI() { let response = await fetch('api/data') response = await response.json() dataSet(response) } fetchMyAPI() }, []) return <div>{JSON.stringify(data)}</div> }

A más largo plazo, desaconsejaremos este patrón porque fomenta las condiciones de carrera. Por ejemplo, cualquier cosa podría pasar entre el comienzo y el final de su llamada, y podría haber obtenido nuevos accesorios. En su lugar, recomendaremos Suspense para la obtención de datos, que se parecerá más a

 const response = MyAPIResource.read();

y sin efectos. Pero mientras tanto, puede mover las cosas asíncronas a una función separada y llamarla.

Puedes leer más sobre suspenso experimental aquí .


Si desea utilizar funciones externas con eslint.

 function OutsideUsageExample({ userId }) { const [data, dataSet] = useState<any>(null) const fetchMyAPI = useCallback(async () => { let response = await fetch('api/data/' + userId) response = await response.json() dataSet(response) }, [userId]) // if userId changes, useEffect will run again useEffect(() => { fetchMyAPI() }, [fetchMyAPI]) return ( <div> <div>data: {JSON.stringify(data)}</div> <div> <button onClick={fetchMyAPI}>manual fetch</button> </div> </div> ) }

Si usa useCallback, mire el ejemplo de cómo funciona useCallback . caja de arena

 import React, { useState, useEffect, useCallback } from "react"; export default function App() { const [counter, setCounter] = useState(1); // if counter is changed, than fn will be updated with new counter value const fn = useCallback(() => { setCounter(counter + 1); }, [counter]); // if counter is changed, than fn will not be updated and counter will be always 1 inside fn /*const fnBad = useCallback(() => { setCounter(counter + 1); }, []);*/ // if fn or counter is changed, than useEffect will rerun useEffect(() => { if (!(counter % 2)) return; // this will stop the loop if counter is not even fn(); }, [fn, counter]); // this will be infinite loop because fn is always changing with new counter value /*useEffect(() => { fn(); }, [fn]);*/ return ( <div> <div>Counter is {counter}</div> <button onClick={fn}>add +1 count</button> </div> ); }
about 3 years ago · Santiago Trujillo Report

0

Cuando usas una función asíncrona como

 async () => { try { const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`); const json = await response.json(); setPosts(json.data.children.map(it => it.data)); } catch (e) { console.error(e); } }

devuelve una promesa y useEffect no espera que la función de devolución de llamada devuelva Promise, sino que espera que no se devuelva nada o que se devuelva una función.

Como solución alternativa para la advertencia, puede utilizar una función asíncrona autoinvocada.

 useEffect(() => { (async function() { try { const response = await fetch( `https://www.reddit.com/r/${subreddit}.json` ); const json = await response.json(); setPosts(json.data.children.map(it => it.data)); } catch (e) { console.error(e); } })(); }, []);

o para hacerlo más limpio, puede definir una función y luego llamarla

 useEffect(() => { async function fetchData() { try { const response = await fetch( `https://www.reddit.com/r/${subreddit}.json` ); const json = await response.json(); setPosts(json.data.children.map(it => it.data)); } catch (e) { console.error(e); } }; fetchData(); }, []);

la segunda solución hará que sea más fácil de leer y lo ayudará a escribir código para cancelar solicitudes anteriores si se activa una nueva o guardar la última respuesta de solicitud en el estado

códigos de trabajoandbox

about 3 years ago · Santiago Trujillo Report

0

Hasta que React proporcione una mejor manera, puede crear un asistente, useEffectAsync.js :

 import { useEffect } from 'react'; export default function useEffectAsync(effect, inputs) { useEffect(() => { effect(); }, inputs); }

Ahora puedes pasar una función asíncrona:

 useEffectAsync(async () => { const items = await fetchSomeItems(); console.log(items); }, []);

Actualizar

Si elige este enfoque, tenga en cuenta que es una mala forma. Recurro a esto cuando sé que es seguro, pero siempre es de mala forma y al azar.

Suspense for Data Fetching , que aún es experimental, resolverá algunos de los casos.

En otros casos, puede modelar los resultados asincrónicos como eventos para que pueda agregar o quitar un agente de escucha según el ciclo de vida del componente.

O puede modelar los resultados asíncronos como un Observable para que pueda suscribirse y darse de baja en función del ciclo de vida del componente.

about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error