Skip to content

Fix web exiting animation in StrictMode#6129

Merged
piaskowyk merged 1 commit intomainfrom
@piaskowyk/fix-strictmode-exiting
Jun 21, 2024
Merged

Fix web exiting animation in StrictMode#6129
piaskowyk merged 1 commit intomainfrom
@piaskowyk/fix-strictmode-exiting

Conversation

@piaskowyk
Copy link
Member

Summary

This PR aims to fixing the web exiting animation when StrictMode is enabled. With StrictMode triggering an additional simulated unmount, our listeners detected the need for an exiting animation. The problem originated from setting visibility = 'hidden' on the original component, which remained present, and creating a copy for animation. As a result, the original component was hidden from view in the DOM tree. The solution proposed is simply to eliminate the hiding of components. This adjustment is safe even for scenarios without StrictMode, as the component that is hidden is removed in the same frame, ensuring consistency with the previous behavior.

before after
Screen.Recording.2024-06-17.at.17.30.07.mov
Screen.Recording.2024-06-17.at.17.29.39.mov

Test plan

code
import { Button } from 'react-native';
import React, { useEffect, useState } from 'react';
import Animated, { FadeOutRight } from 'react-native-reanimated';

function Component() {
  useEffect(() => {
    console.log('Component mounted');
    return () => {
      console.log('Component unmounted');
    };
  }, []);
  return (
    <Animated.View exiting={FadeOutRight.duration(1000)} style={{width: 100, height: 100, borderWidth: 2, backgroundColor: 'lightblue'}} />
  );
}

export default function EmptyExample() {
  const [toggle, setToggle] = useState(true);
  return (
    <React.StrictMode>
    <>
      <Button title="Press me" onPress={() => {
        setToggle(!toggle)
        console.log('Button pressed');
      }} />
      {toggle && <Component />}
    </>
    </React.StrictMode>
  );
}

@piaskowyk piaskowyk requested a review from m-bert June 17, 2024 15:44
m-bert

This comment was marked as outdated.

Copy link
Contributor

@m-bert m-bert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, there's one more thing that I need to investigate

@piaskowyk piaskowyk added this pull request to the merge queue Jun 21, 2024
Merged via the queue into main with commit 15ab0b7 Jun 21, 2024
@piaskowyk piaskowyk deleted the @piaskowyk/fix-strictmode-exiting branch June 21, 2024 10:31
r0h0gg6 pushed a commit to r0h0gg6/react-native-reanimated that referenced this pull request Jul 28, 2025
## Summary

This PR aims to fixing the web exiting animation when StrictMode is
enabled. With StrictMode triggering an additional simulated unmount, our
listeners detected the need for an exiting animation. The problem
originated from setting `visibility = 'hidden'` on the original
component, which remained present, and creating a copy for animation. As
a result, the original component was hidden from view in the DOM tree.
The solution proposed is simply to eliminate the hiding of components.
This adjustment is safe even for scenarios without StrictMode, as the
component that is hidden is removed in the same frame, ensuring
consistency with the previous behavior.

| before | after |
| --- | --- |
| <video
src="https://github.com/software-mansion/react-native-reanimated/assets/36106620/07530231-58e4-429f-bae4-84e876ccc474"
/> | <video
src="https://github.com/software-mansion/react-native-reanimated/assets/36106620/d4c3324d-74bd-4c3a-9c34-29207268ac95"
/> |


## Test plan

<details>
<summary>code</summary>

```js
import { Button } from 'react-native';
import React, { useEffect, useState } from 'react';
import Animated, { FadeOutRight } from 'react-native-reanimated';

function Component() {
  useEffect(() => {
    console.log('Component mounted');
    return () => {
      console.log('Component unmounted');
    };
  }, []);
  return (
    <Animated.View exiting={FadeOutRight.duration(1000)} style={{width: 100, height: 100, borderWidth: 2, backgroundColor: 'lightblue'}} />
  );
}

export default function EmptyExample() {
  const [toggle, setToggle] = useState(true);
  return (
    <React.StrictMode>
    <>
      <Button title="Press me" onPress={() => {
        setToggle(!toggle)
        console.log('Button pressed');
      }} />
      {toggle && <Component />}
    </>
    </React.StrictMode>
  );
}

```

</details>
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 this pull request may close these issues.

2 participants