react-native-reanimated icon indicating copy to clipboard operation
react-native-reanimated copied to clipboard

web: "exiting" animations broken with React's strict mode enabled

Open bradleyayers opened this issue 5 months ago • 2 comments

Description

On Web, under a <StrictMode> React tree, <Animated.View> elements with an exiting animation don't render correctly when they're mounted as a result of setting state (from the useState hook).

It works fine if the element was mounted on the first render of the parent (rather than a later render caused by useState()).

Presumably this bug happens because <StrictMode> causes setState causes the component to re-render twice instead of once.

https://github.com/user-attachments/assets/b5d620b8-2467-4a52-b246-e671be86b15b

Steps to reproduce

  1. Create a <StrictMode> wrapped app.
  2. Add a useState(…)
  3. Conditionally render a <Animated.View exiting={FadeOut}> based on the state.
  4. Update the state to cause the element to render.

Snack or a link to a repository

https://github.com/bradleyayers/RNGH-bugrepro-web-strictmode

Reanimated version

3.17.4

React Native version

0.79.2

Platforms

Web

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

No response

Device

No response

Host machine

None

Device model

No response

Acknowledgements

Yes

bradleyayers avatar Jun 03 '25 01:06 bradleyayers

I dug a bit deeper into this and found what is happening. Under React strict mode, the same React element is being mounted and unmounted and then finally mounted again for the <Animated.View>. The exit animation also runs and as part of that the DOM node children are moved out into a separate DOM element for the animation. But the children are never moved back so when the React element mounts again it's lost all its children and doesn't realise.

For now I've created a patch (targeting 3.17.4) to work around the issue.

react-native-reanimated-npm-3.17.4-d7caed9b50.patch

The strategy used is to move the DOM children back into the element during componentDidMount.

bradleyayers avatar Jun 03 '25 03:06 bradleyayers

I have the same problem, but rerenders are caused by updates of the global state.

szado avatar Jun 17 '25 00:06 szado

I have the same issue

m1chael-sp avatar Jul 15 '25 17:07 m1chael-sp

Here's an updated patch for 4.0.1: react-native-reanimated-npm-4.0.1-40ff4579cd.patch

bradleyayers avatar Jul 31 '25 04:07 bradleyayers

Here's an updated patch for 4.0.1: react-native-reanimated-npm-4.0.1-40ff4579cd.patch

This fixed the issue for me, before the patch I was on 4.1.2. Having both entering and exiting props on react-native-web caused any Animated.View (or MotiView) to not render.

Hoping this gets applied in a new version soon so I don't have to keep the downgrade!

Tellefsonjr avatar Nov 03 '25 21:11 Tellefsonjr

cc @m-bert @MatiPl01 Can we upstream the patch from https://github.com/software-mansion/react-native-reanimated/issues/7613#issuecomment-3138504537?

tomekzaw avatar Nov 04 '25 06:11 tomekzaw