Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refs in memoized elements #3695

Closed
pomber opened this issue Aug 27, 2022 · 2 comments · Fixed by #3696
Closed

refs in memoized elements #3695

pomber opened this issue Aug 27, 2022 · 2 comments · Fixed by #3696

Comments

@pomber
Copy link

pomber commented Aug 27, 2022

Describe the bug

Using useRef and useMemo together produces weird results.

It's easier to explain with code:

function Counter() {
  const [count, setCount] = useState(0);
  const inc = () => setCount(count + 1);

  const ref = useRef(null);
  const element = useMemo(() => <div ref={ref}>hey</div>, []);

  useEffect(() => {
    console.log(ref.current);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={inc}>Increment</button>
      <div key={count}>{element}</div>
    </div>
  );
}

The console.log logs null half of the times. I think ref.current should never be null.

To Reproduce

Steps to reproduce the behavior:

  1. Go to https://codesandbox.io/s/jovial-bouman-1d0yik?file=/components/counter.js
  2. Open codesandbox console
  3. Click on Increment button
  4. See null logged half of the time

Expected behavior

ref.current shouldn't be null. If I remove the useMemo it works as expected.

React works as expected: https://codesandbox.io/s/condescending-gagarin-o29rj6?file=/src/App.js

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Aug 27, 2022

Thank you for the awesome reproduction, after looking at this I can confirm this is an issue on our side.

It seems related to keyed elements. Basically we see the key difference and rather than discarding the entire subtree we still reuse the oldVNodeChildren which does a short-circuit for element as that vnode is referentially equal. Basically we re-parent the element while unmounting the old parent div

@pomber
Copy link
Author

pomber commented Aug 27, 2022

That's funny because I added the key to simplify the example. My real use case doesn't use keys, it unmounts the element, then mounts another tree, and later re-mounts the element.

So, maybe there are two issues. I'll wait until the one you are mentioning is fixed, and try again. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants