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-deps
para 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
useEffect
Má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() Hook
Puede configurarlo directamente como
useEffect
devolució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
useEffect
devolució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
useCallback
matriz de dependencias y esto activaráuseEffect
nuevamente 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 auseEffect
como en1. useEffect(fetchBusinesses, [])
.4. Desactiva la advertencia de eslint
fuente
La solución también está dada por react, los consejos que utiliza
useCallback
que le devolverán una versión memorable de su función:useCallback
es simple de usar ya que tiene la misma firma ya queuseEffect
la 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 unaIF
declaració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
fetchBusinesses
dentro de las dependencias del gancho, simplemente puede pasarlo como un argumento a la devolución de llamada del gancho y establecer el principalfetchBusinesses
como 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
fetchBusinesses
completamente de su componente:Esto no solo proporcionará una solución simple y resolverá la advertencia exhaustiva de profundidad.
fetchBusiness
ahora puede probarse mejor y facilitarseComp
, ya que reside en el alcance del módulo fuera del árbol React.Reubicar
fetchBusinesses
afuera 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
useEffect
dependa de este valor (función de cálculo puro)useCallback
como último recursoEn cuanto a otras soluciones:
Entrar
fetchBusinesses
adentrouseEffect()
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 array
fuente
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í.useEffect
que verifica si el estado está vacío.