"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > When Using React Hooks and Event Listeners, Why Does the State Console Log Display Incorrect Information?

When Using React Hooks and Event Listeners, Why Does the State Console Log Display Incorrect Information?

Published on 2024-11-07
Browse:851

When Using React Hooks and Event Listeners, Why Does the State Console Log Display Incorrect Information?

Event Listeners and React Hooks

Problem: When using React hooks and event listeners, the state console log displays incorrect information.

Problem Description

Consider the provided CodeSandbox: https://codesandbox.io/s/lrxw1wr97m. When you click the "Add card" button twice, and then click "Button1" in the first card, the console correctly displays the state with two cards. However, if you click "Button2" in the same card (which is handled by an event listener), the console incorrectly displays only one card in the state.

Reason for Incorrect State

The issue arises from the different treatment of event handlers in the CardsProvider and Card components. The event handlers defined within the CardsProvider functional component, handleCardClick and handleButtonClick, are re-defined each time the component is rendered. This means that they refer to the state at the moment they are defined, which can be stale when the event listener is triggered.

On the other hand, the Card component uses useRef to register the event listener, which persists throughout the component's lifecycle. As a result, the event listener function refers to the state at the time the component was mounted, which is stale.

Solution - Using State Updater Function

One solution is to use a state updater function that receives fresh state as an argument, rather than relying on the stale state from the enclosing scope:

const eventListener = () => {
  // Function receives fresh state
  setState(freshState => freshState   1);
};

// Event listener is registered using `useEffect` to ensure it is only registered once
useEffect(() => {
  // Register event listener
  // ...

  // Unregister event listener on component unmount
  return () => {
    // ...
  };
}, []);

In this scenario, the event listener receives the fresh state, eliminating the issue with stale data. However, it's important to note that the state updater function can return the same state to prevent unnecessary updates. Use console.log within the state updater function to observe the state changes.

Other Solutions

Alternative ways to address this issue include:

  • Mutable State: Using useRef instead of useState.
  • Manual Event Listener Re-registration: Re-registering the event listener every time the state changes.
  • Built-in Event Handling: Using React's built-in event handling rather than custom event listeners.
Release Statement This article is reprinted at: 1729253539 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3