Sugiero ver la respuesta de Dan Abramov (uno de los mantenedores centrales 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 largo plazo, desalentaremos este patrón porque fomenta las condiciones de carrera. Por ejemplo, cualquier cosa podría suceder entre el comienzo y el final de su llamada, y podría haber obtenido nuevos accesorios. En su lugar, recomendaremos Suspense para obtener datos que se parecerán 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 el suspenso experimental aquí .
Si desea utilizar funciones en el exterior con eslint.
function OutsideUsageExample() {
const [data, dataSet] = useState<any>(null)
const fetchMyAPI = useCallback(async () => {
let response = await fetch('api/data')
response = await response.json()
dataSet(response)
}, [])
useEffect(() => {
fetchMyAPI()
}, [fetchMyAPI])
return (
<div>
<div>data: {JSON.stringify(data)}</div>
<div>
<button onClick={fetchMyAPI}>manual fetch</button>
</div>
</div>
)
}
Con useCallback useCallback . Sandbox .
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>
);
}
useEffect(() => { let unmounted = false promise.then(res => { if (!unmounted) { setState(...) } }) return () => { unmounted = true } }, [])
eslint
me pide que hagafetchMyAPI()
como dependencia deuseEffect
Cuando usa una función asíncrona como
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 temporal a la advertencia, puede utilizar una función asíncrona autoinvocada.
o para hacerlo más limpio, puede definir una función y luego llamarla
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 trabajo y caja
fuente
useEffect
, puede devolver una función para realizar la limpieza, como cancelar la suscripción a eventos. Cuando usa la función asíncrona, no puede devolver nada porqueuseEffect
no esperará el resultadoHasta que React proporcione una forma mejor, puede crear un ayudante
useEffectAsync.js
:Ahora puede pasar una función asincrónica:
fuente
useAsyncEffect
tal como la ha escrito fácilmente podría inducir a error a alguien a pensar que si devuelve una función de limpieza de su efecto asincrónico, se ejecutaría en el momento adecuado. Esto podría provocar pérdidas de memoria o errores peores, por lo que optamos por alentar a las personas a refactorizar su código para hacer más visible la "costura" de las funciones asíncronas que interactúan con el ciclo de vida de React y, como resultado, el comportamiento del código, con suerte, más deliberado y correcto.Leí esta pregunta y siento que la mejor manera de implementar useEffect no se menciona en las respuestas. Supongamos que tiene una llamada de red y le gustaría hacer algo una vez que tenga la respuesta. En aras de la simplicidad, almacenemos la respuesta de la red en una variable de estado. Es posible que desee utilizar action / reducer para actualizar la tienda con la respuesta de la red.
Referencia => https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
fuente
Aquí se podría utilizar el operador vacío .
En vez de:
o
podrías escribir:
Es un poco más limpio y bonito.
Los efectos asincrónicos pueden causar pérdidas de memoria, por lo que es importante realizar una limpieza al desmontar el componente. En caso de recuperación, esto podría verse así:
fuente
tratar
fuente
Para otros lectores, el error puede provenir del hecho de que no hay corchetes que envuelvan la función asíncrona:
Considerando la función asíncrona initData
Este código dará lugar a su error:
Pero este, no lo hará:
(Observe los corchetes alrededor de initData ()
fuente