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

Callbacks are not working while reduceMotion is active #6714

Open
Kolahzary opened this issue Nov 16, 2024 · 3 comments · May be fixed by #6895
Open

Callbacks are not working while reduceMotion is active #6714

Kolahzary opened this issue Nov 16, 2024 · 3 comments · May be fixed by #6895
Assignees
Labels
Platform: Android This issue is specific to Android Repro provided A reproduction with a snippet of code, snack or repo is provided

Comments

@Kolahzary
Copy link

Kolahzary commented Nov 16, 2024

Description

We have some state changes that are covered by animations, for example the following scenario:

  1. Fade out the texts
  2. Change them to the new texts while faded (by changing a number in the state)
  3. Fade in the texts

The second step should wait for the first step to be done, so we run it inside the callback function of the animation.

Now the problem is, if the user doesn't want to see the animations, Reanimated will not run the callback too, so the users with accessibility feature of reduceMotion will be blocked and will not be able to use the app.
Callbacks should be ran anyways, and reduceMotion should only make the animation blink to the final state only.

Steps to reproduce

  1. pass a callback to withTiming
animation.value = withTiming(1, {
  duration: 500,
}, () => {
  console.log('Non-animation related step that should be done after the animation');
}),
  1. Run the code normally, the callback will be executed
  2. Set ReduceMotion to Always (or try your app on a phone with reduceMotion settings active)
<ReducedMotionConfig mode={ReduceMotion.Always} />
  1. the callback will NOT be executed!

Snack or a link to a repository

https://snack.expo.dev/@kolahzary/react-native-animated-reducemotion-bug

Reanimated version

^3.16.1

React Native version

0.75.3

Platforms

Android

JavaScript runtime

None

Workflow

React Native

Architecture

Paper (Old Architecture)

Build type

None

Device

Android emulator

Device model

No response

Acknowledgements

Yes

@github-actions github-actions bot added Platform: Android This issue is specific to Android Missing repro This issue need minimum repro scenario Repro provided A reproduction with a snippet of code, snack or repo is provided and removed Missing repro This issue need minimum repro scenario labels Nov 16, 2024
@Martinocom-Switcho
Copy link

Martinocom-Switcho commented Dec 5, 2024

I can confirm that in our application the same thing happens . In the documentation, I didn't find any info about callback not being called if reduceMotion is true. As workaround we made an explicit check in order to make the change happen anyway, like so:

  const reduceMotion = useReducedMotion();

  //...

  // When reaching the last slide and motion are reduced
  useEffect(() => {
    if (reduceMotion) {
      if (isLastSlide) {
        setButtonContent('text');
      } else {
        setButtonContent('icon');
      }
    }
  }, [isLastSlide, reduceMotion]);

We caught it because our test suite started to fail for no reason.

@rtorrente
Copy link

rtorrente commented Dec 19, 2024

I've noticed the same behavior here, and even though the doc doesn't mention it, it doesn't seem to me to be the behavior logically expected in this case.

When using a runOnJs function on a withCallback to execute a function on the application at the end of an animation. The animation will never take place, which is very difficult to debug when the user reports a problem and we don't suspect that he has disabled animations.

If this is how it's supposed to work, it should be explicitly stated in the documentation.

Edit : It appear that the callback is not called only on Layout Animation (In my case with entering and exiting props on Animated component specified).
If a call an animation with a useEffect and withTiming, the callback is correctly called.

@patrycjakalinska
Copy link
Contributor

patrycjakalinska commented Jan 14, 2025

Hi @Kolahzary, thank you for opening this issue! c: By default, callbacks were not designed to run in withSequence animations when reduce motion was enabled. However, following this thread, we’ve decided to enable callbacks in this scenario. I've opened a PR fixing this issue. Feel free to take a look and ask any additional questions c:

@patrycjakalinska patrycjakalinska self-assigned this Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Android This issue is specific to Android Repro provided A reproduction with a snippet of code, snack or repo is provided
Projects
None yet
4 participants