• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

212
Views
Determinar qué variable de la matriz de dependencia provocó el disparo del gancho useEffect

¿Hay una manera fácil de determinar qué variable en la matriz de dependencia de useEffect desencadena una función que se vuelve a activar?

Simplemente cerrar la sesión de cada variable puede ser engañoso, si a es una función b es un objeto, pueden aparecer iguales cuando se registran, pero en realidad son diferentes y provocan incendios de useEffect.

Por ejemplo:

 React.useEffect(() => { // which variable triggered this re-fire? console.log('---useEffect---') }, [a, b, c, d])

Mi método actual ha sido eliminar las variables de dependencia una por una hasta que me doy cuenta del comportamiento que causa llamadas useEffect excesivas, pero debe haber una mejor manera de reducir esto.

over 3 years ago · Santiago Trujillo
3 answers
Answer question

0

Terminé tomando un poco de varias respuestas para hacer mi propio gancho para esto. Quería la capacidad de colocar algo en lugar de useEffect para depurar rápidamente qué dependencia estaba activando useEffect .

 const usePrevious = (value, initialValue) => { const ref = useRef(initialValue); useEffect(() => { ref.current = value; }); return ref.current; };
 const useEffectDebugger = (effectHook, dependencies, dependencyNames = []) => { const previousDeps = usePrevious(dependencies, []); const changedDeps = dependencies.reduce((accum, dependency, index) => { if (dependency !== previousDeps[index]) { const keyName = dependencyNames[index] || index; return { ...accum, [keyName]: { before: previousDeps[index], after: dependency } }; } return accum; }, {}); if (Object.keys(changedDeps).length) { console.log('[use-effect-debugger] ', changedDeps); } useEffect(effectHook, dependencies); };

A continuación se muestran dos ejemplos. Para cada ejemplo, asumo que dep2 cambia de 'foo' a 'bar'. El ejemplo 1 muestra el resultado sin pasar dependencyNames y el ejemplo 2 muestra un ejemplo con dependencyNames .

Ejemplo 1

Antes:

 useEffect(() => { // useEffect code here... }, [dep1, dep2])

Después:

 useEffectDebugger(() => { // useEffect code here... }, [dep1, dep2])

Salida de la consola:

 { 1: { before: 'foo', after: 'bar' } }

La clave de objeto '1' representa el índice de la dependencia que cambió. Aquí, dep1 cambió y es el segundo elemento de la dependencia, o índice 1

Ejemplo 2

Antes:

 useEffect(() => { // useEffect code here... }, [dep1, dep2])

Después:

 useEffectDebugger(() => { // useEffect code here... }, [dep1, dep2], ['dep1', 'dep2'])

Salida de la consola:

 { dep2: { before: 'foo', after: 'bar' } }
over 3 years ago · Santiago Trujillo Report

0

Esta biblioteca... @simbathesailor/use-what-changed , ¡Funciona de maravilla!

  1. Install con npm/yarn y --dev o --no-save
  2. Añadir importación:
 import { useWhatChanged } from '@simbathesailor/use-what-changed';
  1. Llámalo:
 // (guarantee useEffect deps are in sync with useWhatChanged) let deps = [a, b, c, d] useWhatChanged(deps, 'a, b, c, d'); useEffect(() => { // your effect }, deps);

Crea este bonito gráfico en la consola:

image loaded from github

Hay dos culpables comunes:

  1. Algunos objetos se pasan así:
 // Being used like: export function App() { return <MyComponent fetchOptions={{ urlThing: '/foo', headerThing: 'FOO-BAR' }) } export const MyComponent = ({fetchOptions}) => { const [someData, setSomeData] = useState() useEffect(() => { window.fetch(fetchOptions).then((data) => { setSomeData(data) }) }, [fetchOptions]) return <div>hello {someData.firstName}</div> }

La solución en el caso del objeto, si puede, desglose un objeto estático fuera del renderizado del componente:

 const fetchSomeDataOptions = { urlThing: '/foo', headerThing: 'FOO-BAR' } export function App() { return <MyComponent fetchOptions={fetchSomeDataOptions} /> }

También puede envolver en useMemo:

 export function App() { return <MyComponent fetchOptions={ useMemo( () => { return { urlThing: '/foo', headerThing: 'FOO-BAR', variableThing: hash(someTimestamp) } }, [hash, someTimestamp] ) } /> }

El mismo concepto se aplica a las funciones hasta cierto punto, excepto que puede terminar con cierres obsoletos.

over 3 years ago · Santiago Trujillo Report

0

ACTUALIZAR

Después de un poco de uso en el mundo real, hasta ahora me gusta la siguiente solución que toma prestados algunos aspectos de la solución de Retsam:

 const compareInputs = (inputKeys, oldInputs, newInputs) => { inputKeys.forEach(key => { const oldInput = oldInputs[key]; const newInput = newInputs[key]; if (oldInput !== newInput) { console.log("change detected", key, "old:", oldInput, "new:", newInput); } }); }; const useDependenciesDebugger = inputs => { const oldInputsRef = useRef(inputs); const inputValuesArray = Object.values(inputs); const inputKeysArray = Object.keys(inputs); useMemo(() => { const oldInputs = oldInputsRef.current; compareInputs(inputKeysArray, oldInputs, inputs); oldInputsRef.current = inputs; }, inputValuesArray); // eslint-disable-line react-hooks/exhaustive-deps };

Esto se puede usar copiando un literal de matriz de dependencia y simplemente cambiándolo para que sea un objeto literal:

 useDependenciesDebugger({ state1, state2 });

Esto permite que el registro conozca los nombres de las variables sin ningún parámetro separado para ese propósito.

Editar useDependenciesDebugger

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error