Skip to content
Advertisement

Why I’m not getting latest prop value inside an event handler which I register when component mounted?

I’m creating a Counter component and passing count as a prop from the parent component.

When the Counter component is mounted, I’m registering a focus event handler on the window object.

Whenever the window gets focused I’m trying to print the count prop value in the console. But I’m not getting the latest count prop value instead I’m getting the initial count value.

Is it happening because whenever there is a change in any prop, new props object gets created in memory and passed to the child component, and as I’m not attaching my event handler whenever there is a change in the count prop, I’m getting the initial prop ( stale prop ) value because displayCount function is not attached to focus event again and still pointing to the old reference of the props object?

Please correct me if I’m wrong.

Using a ref will work. But I’m interested in knowing what exactly is the reason behind this behavior.

//CounterDisplay.js

import React, { useEffect, useRef } from 'react';

const CounterDisplay = (props) => {
    const { count } = props;
    const countRef = useRef(count);

    useEffect(() => {
        window.addEventListener('focus', displayCount);

        return(() => {
            window.removeEventListener('focus', displayCount);

        });
    },[]);

    useEffect(() => {
        countRef.current = count;
    },[count]);

    const displayCount = () => {
        console.log(" count prop -> "+ props.count);
        console.log(" countRef -> "+ countRef.current);
    }

    return (
        <h1>{count}</h1>
    );
}

export default CounterDisplay;

Advertisement

Answer

You’re missing a dependency in the dependency array of your first useEffect. You can try to restructure your code to something like this, and see if that works. In the current version, your useEffect does not update when props changes, since you provide an empty dependency array.

import React, { useEffect, useRef } from 'react';

const CounterDisplay = (props) => {
    const { count } = props;
    const countRef = useRef(count);

    useEffect(() => {
        const displayCount = () => {
          console.log(" count prop -> "+ count);
          console.log(" countRef -> "+ countRef.current);
        }
    
        window.addEventListener('focus', displayCount);

        return(() => {
            window.removeEventListener('focus', displayCount);

        });
    },[count]);

    useEffect(() => {
        countRef.current = count;
    },[count]);

    return (
        <h1>{count}</h1>
    );
}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement