Browse React Native
React NativeHooksNo. 21 of 22
useReducedMotion
Whether Reduce Motion is on in the device's accessibility settings, following changes while the app is open.
Preview
Loading the preview
The gallery's web build, through react-native-web. On a phone the same code draws native views.
Installation
npx shadcn@latest add @corsair-native/use-reduced-motionThe app's components.json needs the @corsair-native registry first; see Installation. The files land in your project as source: edit them like your own code.
API
Read from the source's own comments and types. Props marked * are required.
useReducedMotionHook
Whether "Reduce motion" is on in the device's accessibility settings (on the web, prefers-reduced-motion). It follows changes while the app is open. The first render of the first component uses false until the system answers; later mounts start with the last answer, so they do not animate when they should not.
Returns boolean.
const reduced = useReducedMotion();
Animated.timing(opacity, { toValue: 1, duration: reduced ? 0 : 200, useNativeDriver: true });Compatibility
- Expo SDK
- 54 and 57, both checked in CI
- React Native
- 0.81 and 0.86, New Architecture
- Web
- Expo's web target, through react-native-web
Source
1 file, installed as source you own
use-reduced-motion.tsView on GitHubimport { useEffect, useState } from "react";
import { AccessibilityInfo } from "react-native";
/** The last answer from the system, so components mounted later start with it. */
let lastKnown = false;
/**
* Whether "Reduce motion" is on in the device's accessibility settings (on
* the web, `prefers-reduced-motion`). It follows changes while the app is
* open. The first render of the first component uses `false` until the system
* answers; later mounts start with the last answer, so they do not animate
* when they should not.
*
* @example
* const reduced = useReducedMotion();
* Animated.timing(opacity, { toValue: 1, duration: reduced ? 0 : 200, useNativeDriver: true });
*/
function useReducedMotion(): boolean {
const [reduced, setReduced] = useState(lastKnown);
useEffect(() => {
let active = true;
const update = (value: boolean) => {
lastKnown = value;
if (active) setReduced(value);
};
AccessibilityInfo.isReduceMotionEnabled().then(update, () => {});
const subscription = AccessibilityInfo.addEventListener("reduceMotionChanged", update);
return () => {
active = false;
// react-native-web returns nothing where the browser lacks matchMedia.
subscription?.remove();
};
}, []);
return reduced;
}
export { useReducedMotion };