Con React 16.8.6 (fue bueno en la versión anterior 16.8.3), obtengo este error cuando intento evitar un bucle infinito en una solicitud de recuperación
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
No he podido encontrar una solución que detenga el ciclo infinito. Quiero alejarme del uso useReducer(). Encontré esta discusión https://github.com/facebook/react/issues/14920 donde una posible solución es You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.que no estoy seguro de lo que estoy haciendo, así que todavía no he intentado implementarlo.
Tengo esta configuración actual React hook useEffect se ejecuta continuamente para siempre / bucle infinito y el único comentario es sobre el useCallback()que no estoy familiarizado.
Cómo estoy usando actualmente useEffect()(que solo quiero ejecutar una vez al principio, similar a componentDidMount())
useEffect(() => {
fetchBusinesses();
}, []);
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
});
};

useCallback(). Entonces, por ejemplo:const fetchBusinesses= useCallback(() => { ... }, [...])yuseEffect()se vería así:useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);// eslint-disable-next-line react-hooks/exhaustive-depspara explicarle a la interfaz que tu código es correcto es como un hack. Espero que encuentren otra solución para hacer que el linter sea lo suficientemente inteligente como para detectar cuando un argumento no es obligatorioNo es un error JS / React sino una advertencia de eslint (eslint-plugin-react-hooks).
Le dice que el gancho depende de la función
fetchBusinesses, por lo que debe pasarlo como dependencia.Podría provocar la invocación de la función cada render si la función se declara en un componente como:
porque cada vez que la función se redeclara con nueva referencia
La forma correcta de hacer esto es:
o simplemente definiendo la función en
useEffectMás: https://github.com/facebook/react/issues/14920
fuente
Line 20: The 'fetchBusinesses' function makes the dependencies of useEffect Hook (at line 51) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'fetchBusinesses' definition into its own useCallback() HookPuede configurarlo directamente como
useEffectdevolución de llamada:Se activará solo una vez, así que asegúrese de que todas las dependencias de la función estén configuradas correctamente (lo mismo que usar
componentDidMount/componentWillMount...)Editar 21/02/2020
Solo para completar:
1. Use la función como
useEffectdevolución de llamada (como arriba)2. Declarar función dentro
useEffect()3. Recuerda con
useCallback()En este caso, si tiene dependencias en su función, deberá incluirlas en la
useCallbackmatriz de dependencias y esto activaráuseEffectnuevamente si los parámetros de la función cambian. Además, es un montón de repeticiones ... Así que simplemente pase la función directamente auseEffectcomo en1. useEffect(fetchBusinesses, []).4. Desactiva la advertencia de eslint
fuente
La solución también está dada por react, los consejos que utiliza
useCallbackque le devolverán una versión memorable de su función:useCallbackes simple de usar ya que tiene la misma firma ya queuseEffectla diferencia es que useCallback devuelve una función. Se vería así:fuente
Estas advertencias son muy útiles para encontrar componentes que no se actualizan constantemente: https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- dependencias .
Sin embargo, si desea eliminar las advertencias en todo su proyecto, puede agregar esto a su configuración de eslint:
fuente
Este artículo es una buena introducción a la obtención de datos con ganchos: https://www.robinwieruch.de/react-hooks-fetch-data/
Esencialmente, incluya la definición de la función de búsqueda dentro
useEffect:fuente
Puede eliminar el segundo tipo de matriz de argumentos,
[]perofetchBusinesses()también se llamará a cada actualización. Puede agregar unaIFdeclaración a lafetchBusinesses()implementación si lo desea.El otro es implementar la
fetchBusinesses()función fuera de su componente. Simplemente no olvide pasar ningún argumento de dependencia a sufetchBusinesses(dependency)llamada, si corresponde.fuente
En realidad, las advertencias son muy útiles cuando se desarrolla con ganchos. pero en algunos casos, puede hacerte una aguja. especialmente cuando no necesita escuchar el cambio de dependencias.
Si no desea colocar
fetchBusinessesdentro de las dependencias del gancho, simplemente puede pasarlo como un argumento a la devolución de llamada del gancho y establecer el principalfetchBusinessescomo el valor predeterminado para ello de esta maneraNo es la mejor práctica, pero podría ser útil en algunos casos.
Además, como escribió Shubnam, puede agregar el siguiente código para indicarle a ESLint que ignore la comprobación de su enlace.
fuente
Puede sacar
fetchBusinessescompletamente de su componente:Esto no solo proporcionará una solución simple y resolverá la advertencia exhaustiva de profundidad.
fetchBusinessahora puede probarse mejor y facilitarseComp, ya que reside en el alcance del módulo fuera del árbol React.Reubicar
fetchBusinessesafuera funciona bien aquí, ya que solo podríamos leer los accesorios iniciales y el estado del componente de todos modos debido al alcance de cierre obsoleto ([]dep inuseEffect).Cómo omitir dependencias de funciones
useEffectdependa de este valor (función de cálculo puro)useCallbackcomo último recursoEn cuanto a otras soluciones:
Entrar
fetchBusinessesadentrouseEffect()realmente no ayuda, si accede a otro estado en él. Eslint todavía se quejaría: Codesandbox .También me mantendría alejado de eslint exhaustivo-deps ignorar los comentarios. Es fácil olvidarlos cuando refactoriza y revisa sus dependencias.
fuente
Esta solución es bastante simple y no necesita anular las advertencias de es-lint. Simplemente mantenga una bandera para verificar si el componente está montado o no.
fuente
intentas de esta manera
y
Es trabajo para ti. Pero mi sugerencia es que intente de esta manera también le funcione Es mejor que antes. Yo uso de esta manera:
si obtiene datos sobre la base de una identificación específica, agregue el efecto de devolución de llamada useEffect
[id]y no pueda mostrarle la advertenciaReact Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency arrayfuente
simplemente deshabilite eslint para la siguiente línea;
de esta manera lo está utilizando como si un componente se hubiera montado (llamado una vez)
actualizado
o
fetchBusinesses se llamará cada vez que someDeps cambie
fuente
[fetchBusinesses]eliminará automáticamente la advertencia y eso resolvió el problema para mí.useEffectque verifica si el estado está vacío.