Master React Native Reanimated Part 2 (Layout Animation)

Steve Blue
2 min readAug 17, 2023

--

Previous part Master React Native Reanimated Part 1

Before starting with Layout Animation, let’s take a look at some concepts

  1. Animated.createAnimatedComponent: when you want to create animations, you can use the Animated API to animate the properties of components in a way that's optimized for performance. However, some components might not be directly compatible with the Animated API. This is where createAnimatedComponent comes in. By using Animated.createAnimatedComponent, you're essentially creating a bridge between your original component and the Animated API, allowing you to animate its properties efficiently. This can be particularly useful when you need to animate custom components or components from third-party libraries that don't natively support the Animated API.
  2. SlideInRight, SlideOutRight: Typically, when animating components using React Native Reanimated, you create custom animations by defining how properties of the components change over time. For instance, to create a “SlideInRight” animation, you would define an animation that changes the translateX property of a component to make it appear as if it's sliding in from the right. Similarly, "SlideOutRight" could be implemented by animating the translateX property to make the component slide out to the right.
  3. Layout.springify() that helps to create spring animations for layout changes. Springs are a type of animation that simulates the behavior of a physical spring, providing a more natural and elastic motion to animations.Layout.springify() takes in a layout, and then you can animate its properties using spring animations

Let’s check out how to implement it with FlatList and Layout Animation

// react
import React, {
FC,
Fragment,
useCallback,
useEffect,
useRef,
useState,
} from 'react';

// modules
import {FlatList, Pressable, Text} from 'react-native';
import Animated, {
Layout,
SlideInRight,
SlideOutRight,
} from 'react-native-reanimated';

// styles
import styles from './layout-animation.styles';

const AnimatedFlatList = Animated.createAnimatedComponent(FlatList<number>);

const LayoutAnimation: FC = () => {
const isInit = useRef<boolean>(true);
const [data, setData] = useState<Array<number>>([1, 2, 3]);

const handleAddOnPress = useCallback(() => {
setData(prev => [...prev, (prev[prev.length - 1] || 0) + 1]);
}, []);

const renderCell = useCallback((props: any) => {
return (
<Animated.View
{...props}
entering={
isInit.current ? SlideInRight.delay(props.index * 200) : SlideInRight
}
exiting={SlideOutRight}
layout={Layout.springify()}
/>
);
}, []);

useEffect(() => {
isInit.current = false;
}, []);

return (
<Fragment>
<AnimatedFlatList
data={data}
keyExtractor={item => item.toString()}
renderItem={({item}) => (
<Animated.View
onTouchEnd={() => {
setData(prevState => prevState.filter(fItem => fItem !== item));
}}
key={item}
style={styles.itemList}>
<Text>{item}</Text>
</Animated.View>
)}
CellRendererComponent={renderCell}
/>

<Pressable style={styles.button} onPress={handleAddOnPress}>
<Text style={styles.buttonText}>+</Text>
</Pressable>
</Fragment>
);
};

export default LayoutAnimation;

--

--

Steve Blue

Experienced Mobile Application Developer with a demonstrated history of working in the computer software industry.