Master React Native Reanimated Part 2 (Layout Animation)
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
- 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 theAnimated
API. This is wherecreateAnimatedComponent
comes in. By usingAnimated.createAnimatedComponent
, you're essentially creating a bridge between your original component and theAnimated
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 theAnimated
API. - 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 thetranslateX
property to make the component slide out to the right. - 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;