Considere este ejemplo:
let memoizedCb = React.useCallback( memoize((param) => () => someFunction(param)), [] );
donde memoize
es de una biblioteca externa como "memoize rápido". El código anterior da una advertencia:
React Hook useCallback recibió una función cuyas dependencias se desconocen. Pase una función en línea en su lugar
Encontré este hilo que, si nos adaptamos a mi caso de uso, sugeriría esto como solución ( si no me equivoco ):
const memoizedCb = React.useMemo( () => memoize((param) => () => someFunction(param)), [] );
¿De qué se trata la advertencia? ¿ Por qué useMemo
soluciona este problema?
NOTA: someFunction
se define fuera del componente de función, por lo que no se necesita como dependencia.
Parece que la advertencia está ahí porque useCallback
(y también useMemo
ver más abajo) espera una función en línea como argumento (aunque no sé por qué).
Así que en la solución de la pregunta:
const memoizedCb = React.useMemo( () => memoize((param) => () => someFunction(param)), [] );
usaron useMemo
para imitar la funcionalidad useCallback
mientras también pasaban una función en línea a useMemo
como la advertencia requerida:
React Hook useCallback recibió una función cuyas dependencias se desconocen. Pase una función en línea en su lugar
Esa advertencia no es específica de useCallback
, recibe la misma advertencia si simplemente reemplaza useCallback
con useMemo
en el primer ejemplo:
// For testing // Gives same warning let memoizedCb = React.useMemo( memoize((param) => () => someFunction(param)), [] );
Hasta donde yo sé, useCallback espera una función en línea. Si pasa una función devuelta desde otra función, eslint no podrá averiguar cuáles son las dependencias de la función, por lo que mostrará esta advertencia.
Aquí creo que eslint no puede determinar las dependencias de somefunction
y, por lo tanto, no puede evaluar la regla react-hooks/exhaustive-deps
porque para evaluar esta regla, eslint debería poder identificar si existe alguna dependencia como estado, apoyos para la función aprobada para usar el gancho de devolución de llamada. Entonces, eslint le pide que pase una función en línea que comprenderá y puede evaluar para las reglas de pelusa.
Como una explicación más general, lo siguiente producirá una advertencia:
const someFuncWrap = (fn) => (e) => fn(e) const memoizedFunc = useCallback(someFuncWrap(foo), [someFuncWrap, foo]);
Se pasa el cambio de useCallback
a useMemo
con una función en línea.
const someFuncWrap = (fn) => (e) => fn(e) const memoizedFunc = useMemo(() => someFuncWrap(foo), [someFuncWrap, foo]);
Esto se debe a que, para analizar el gancho, eslint necesita verlo de la siguiente forma:
useMemo(() => foo, [foo]); useCallback((bar) => foo(bar), [foo]);