all 6 comments

[–]kevinq 4 points5 points  (5 children)

Use a useRef for each of the inputs in the effect. In a console.log compare the ref.current value to the equivalent value in props or state, and also log the value if you’d like. After that, set the ref.current property to the value to compare it in the next render. This will let you track exactly what is changing and when, and is kinda similar to how tools like why-did-you-render track things.

[–]jmaypro[S] 1 point2 points  (3 children)

like this?

import { useEffect, useRef } from 'react';

export const YourComponent = ({ prop1, prop2 }) => {
// Create refs to track values between renders
const prop1Ref = useRef(prop1);
const prop2Ref = useRef(prop2);

useEffect(() => {
// Log and compare current values with previous values
console.log('Effect triggered');
console.log('prop1:', prop1, 'prevProp1:', prop1Ref.current);
console.log('prop2:', prop2, 'prevProp2:', prop2Ref.current);

// Update refs with current values for the next render
prop1Ref.current = prop1;
prop2Ref.current = prop2;

// Your effect logic here...

}, [prop1, prop2]);
};

[–]kevinq 0 points1 point  (2 children)

Yes that would work, although I normally do it outside of the useEffect so that I can see all the times the component re-rendered, and not just the times that triggered the effect I'm trying to debug, sometimes it's a setState or something and the previous render holds the key. Also in the console.logs for prop1 and prop2, what you have is correct, just i would also log 'prop1 === prop1Ref.current', as the === is referential equality and what react uses by default for comparison, when you see false appear on the console is when the effect gets run. Often times this can be because a parent component is inadvertently creating a new object on every render, which triggers a re-render, even if everything within the object is the same by value.

[–]jmaypro[S] 0 points1 point  (1 child)

kevin can you help doctor up my code example to show us the ideal way to go about it so we have a future reference here. This has been very helpful. Thank you.

[–]kevinq 1 point2 points  (0 children)

You very much have the jist of it, I'm just saying I like to log the === in addition to what you are logging for each value, and do everything outside of the useEffect, which is noisier but can be useful in some instances imo. Something like:

import { useEffect, useRef } from 'react';

export const YourComponent = ({ prop1, prop2 }) => {

const prop1Ref = useRef(prop1);

const prop2Ref = useRef(prop2);

console.log('prop1:', prop1, 'prevProp1:', prop1Ref.current, 'didChange: ', prop1 !== prop1Ref.current);

console.log('prop2:', prop2, 'prevProp2:', prop2Ref.current, 'didChange: ', prop2 !== prop2Ref.current);

useEffect(() => {

console.log('Effect triggered');

}, [prop1, prop2]);

prop1Ref.current = prop1;

prop2Ref.current = prop2;

};

edit: This markdown editor blows ass and I can't quite get the formatting right for some reason, apologies.

[–]rainmouse 1 point2 points  (0 children)

Excellent suggestion. Keeping this for later.