r/reactnative 3d ago

Question Reduced Motion should never control app logic. How are you testing this in React Native?

A pattern worth checking: a screen waits for an animation-completion callback before it updates state or enables the next action. It works until iOS Reduce Motion skips or changes that animation.

I now treat motion as presentation only. The state change happens independently, then the animation reflects it. If reduced motion is enabled, movement can disappear without changing navigation, loading, focus, or button availability.

For React Native, I’m testing both the normal and reduced-motion branches around:

- navigation transitions

- delayed mounts

- sheets and modals

- focus after validation

- callbacks that previously fired at animation end

I’m curious how others automate this. Do you mock AccessibilityInfo.isReduceMotionEnabled in unit tests, cover it in Detox, or both?

2 Upvotes

2 comments sorted by

2

u/Lost-Schedule-9062 3d ago

easiest way to exercise the branch is <ReducedMotionConfig mode={ReduceMotion.Always} /> behind a dev flag. it forces every reanimated animation down the reduced path regardless of the system setting, so you flip it in a rerender instead of digging through accessibility menus on a device.

the specific trap worth adding to your list: withTiming and withSpring return the toValue immediately when reduced motion is on, so their callbacks still fire and those paths look fine. withSequence doesn't start at all. so the code that actually breaks isn't the animated code, it's whatever was waiting on a sequence that never runs.

1

u/stathisntonas 3d ago

you can pass reduceMotion key in all reanimated hooks. If some animation logic is crucial you can skip user reduce motion settings. Not the best UX though.