Search code examples
javascriptreactjsreact-hooksfrontend

A question about Status Snapshot and re-rendering from react document


A question from react document:

for below example here is my understanding:

  • on change <input> element triggers rerender
  • State "text" should be updated after rerendering
  • for the time handleSend() was called (the timeout was set), "text" holds the initial value
  • after 3 seconds the callback was executed, "text" should be updated if we have changed value in the input box, because the component's already rerendered.

The rerender must happen way faster before the callback, can't figure out why it still prints the initial value and useRef() must be used instead.

import { useState, useRef } from 'react';

export default function Chat() {
  const [text, setText] = useState('');

  function handleSend() {
    setTimeout(() => {
      alert('Sending: ' + text);
    }, 3000);
  }

  return (
    <>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button
        onClick={handleSend}>
        Send
      </button>
    </>
  );
}

https://react.dev/learn/referencing-values-with-refs challenges #4


Solution

  • I think above is just how Javascript works. Following would be my hypotheses of the phenomena.

    When you create / define a function, it assigns a reference to it, Even though your execution of alert is delayed, you are initiating handleSend with value of text intact.

    When you define a function, its similar to Object (you can read it (here)). Hence when it gets invoked, its invoking that particular referenced function only.

    Which has the older value of specific variable, as states are references as well, it won't read the updated value, due to having used older reference as value in the function definition.