Con React 16.8.6 (estaba bien en la versión anterior 16.8.3), obtengo este error cuando intento evitar un bucle infinito en una petición de obtención
./src/components/BusinessesList.js
Línea 51: React Hook useEffect tiene una dependencia que falta: 'fetchBusinesses'.
Inclúyelo o elimina el array de dependencia react-hooks/exhaustive-deps
No he podido encontrar una solución que detenga el bucle infinito. Quiero evitar el uso de useReducer()
. Encontré esta discusión https://github.com/facebook/react/issues/14920 donde una posible solución es Siempre puedes // eslint-disable-next-line react-hooks/exhaustive-deps si crees que sabes lo que estás haciendo.
No estoy seguro de lo que estoy haciendo así que no he intentado implementarlo todavía.
Tengo esta configuración actual https://stackoverflow.com/questions/53243203/react-hook-useeffect-runs-continuously-forever-infinite-loop y el único comentario es sobre useCallback()
con el que no estoy familiarizado.
Cómo estoy utilizando actualmente useEffect()
(que sólo quiero ejecutar una vez en el principio similar a componentDidMount()
)
useEffect(() => {
fetchBusinesses();
}, []);
const fetchBusinesses = () => {
return fetch("laURL", {método: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdNegocios => {
// algunas cosas
})
.catch(err => {
// algunos errores
});
};
Si no está utilizando el método fetchBusinesses en ningún lugar aparte del efecto, podría simplemente moverlo al efecto y evitar la advertencia
useEffect(() => {
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// some stuff
})
.catch(err => {
// some error handling
});
};
fetchBusinesses();
}, []);
Sin embargo, si está utilizando fetchBusinesses fuera del render, debe tener en cuenta dos cosas
fetchBusinesses
como método y que al ser utilizado durante el montaje con su cierre adjunto no tendrá ningún problema.Para resumir, yo diría que si estás usando fetchBusinesses
fuera de useEffect
puedes deshabilitar la regla usando // eslint-disable-next-line react-hooks/exhaustive-deps
de lo contrario puedes mover el método dentro de useEffect
Para deshabilitar la regla debes escribirla como
useEffect(() => {
// other code
...
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
./src/components/BusinessesList.js
Línea 51: React Hook useEffect tiene una dependencia que falta: 'fetchBusinesses'.
Inclúyelo o elimina el array de dependencia react-hooks/exhaustive-deps
No es un error de JS/React sino una advertencia de eslint (eslint-plugin-react-hooks).
Te dice que el hook depende de la función fetchBusinesses
, por lo que debes pasarla como dependencia.
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
Podría resultar en la invocación de la función cada render si la función se declara en el componente como:
const Component = () => {
/*...*/
//nueva declaración de función cada vez que se renderiza
const fetchBusinesses = () => {
fetch('/api/businesses/')
.then(...)
}
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
/*...*/
}
porque cada vez que se vuelve a declarar la función con una nueva referencia
La forma correcta de hacer estas cosas es
const Component = () => {
/*...*/
// mantener la referencia a la función
const fetchBusinesses = useCallback(() => {
fetch('/api/businesses/')
.then(...)
}, [/* dependencias adicionales */])
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
/*...*/
}
o simplemente definir la función en useEffect
.
Este artículo es un buen manual sobre la obtención de datos con ganchos: https://www.robinwieruch.de/react-hooks-fetch-data/
Básicamente, incluye la definición de la función fetch dentro de useEffect
:
useEffect(() => {
const fetchBusinesses = () => {
return fetch("theUrl"...
// ...your fetch implementation
);
}
fetchBusinesses();
}, []);