React Native Notes 33: Lottie Animations are stopped after the app goes to the background state

Kuray Ogun
FreakyCoder Software Blog

--

Lottie animations are stopped when the app is in the background and do not re-play

Unfortunately, lottie-react-native library does not handle this problem by itself for years so we have to write a wrapper to handle this use case.

Solution

import LottieView from 'lottie-react-native';
import React, { Component, useEffect, useRef, useState } from 'react';
import { AppState, AppStateStatus } from 'react-native';

type extractComponentPropsType<Type> = Type extends Component<infer X>
? X
: null;

// See https://github.com/react-native-community/lottie-react-native/issues/426
type LottieProps = extractComponentPropsType<LottieView>;

// Because Lottie has a bug that stops animation when in background (ios)
// See https://github.com/react-native-community/lottie-react-native/issues/412
const Lottie: React.FC<LottieProps> = ({ ...rest }) => {
const [appState, setAppState] = useState(AppState.currentState);

const lottieRef = useRef<LottieView>(null);

useEffect(() => {
const appStateSubscription = AppState.addEventListener(
'change',
handleAppStateChange
);
return () => {
appStateSubscription.remove();
};
});

const handleAppStateChange = (nextAppState: AppStateStatus) => {
if (appState.match(/inactive|background/) && nextAppState === 'active') {
if (lottieRef.current) {
lottieRef.current.play();
}
}
setAppState(nextAppState);
};

return <LottieView ref={lottieRef} {...rest} />;
};

export default Lottie;

As you can see, the solution is actually pretty simple. All we do is check if the AppState is in the background and coming to an active state and replay the Lottie animation itself.

Usage

There is literally no change on the usage part, all you need to do is import this wrapper instead of lottie-react-native

<Lottie
loop
autoPlay
style={styles.lottieAnimation}
source={require("../assets/lottie-animation.json")}
/>

That’s all folks! Your animations should play even if the app is coming from the background :)

Happy coding!

Credit: The solution is mainly coming from slorber’s answer on Github. I just converted it to a functional component.

--

--