react: Bug: setState updater called but not rendered, in Safari, in concurrent mode

React version: 18.0.0-alpha-9175f4d15-20210928

Steps To Reproduce

Minimal reproduction in this codesandbox.

This issue only appears in Safari, including mobile Safari. It works fine in Chrome and Firefox.

In order to reproduce, you’ll need to:

  1. Render the app with createRoot in the latest 18.0 alpha
  2. Within an element’s ref function, append an iframe to that element using appendChild

The following steps have been removed after simplifying the reproduction:

1. Make a state change originating in a message from a YouTube embed iframe. I assume the same issue would occur with messages from other cross domain iframes, although I have not tested this. The issue does not appear when making an async state change through setTimeout. 2. Render a tooltip using the “tippy.js” library. I haven’t dug into what inside of Tippy is causing this, but commenting out the tippy element resolves the issue. I have confirmed that rendering a simple portal does not reproduce the issue.

Link to code example:

https://codesandbox.io/s/black-moon-ymw10?file=/src/index.js

The current behavior

In the example in safari, the updater function passed to setState is run (confirmed with the “run state updater” console.log)… but the new state is never passed to the component function, leaving the app hanging with no error message, and displaying “not done”.

The expected behavior

In Chrome and Firefox, the App component updates after the state updater function is called, as expected, displaying “done”.


Thanks for all the wonderful work on React, btw! It’s been a lot of fun playing with the new concurrent React features. Can’t wait to see them hit a stable release!

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17

Most upvoted comments

That one’s fixed in 18.2 which was released yesterday.

I’ve played with this a little more and managed to reproduce the issue without any dependencies other than React: https://codesandbox.io/s/black-moon-ymw10?file=/src/index.js

The trigger seems to be appending an iframe to an element within its ref function. Appending a div does not cause the issue, and rendering a <iframe /> element using React (instead of manually appending with appendChild) also avoids the issue.

Will update the steps to reproduce.