Animated Components

Animated Components and createAnimatedComponent

A plain View cannot take an Animated.Value in its style. Animated exports six wrapped components (View, Text, Image, ScrollView, FlatList, SectionList), and createAnimatedComponent() wraps anything else. The wrapper subscribes to the values in its props. When an animation runs on the JavaScript side, the wrapper applies each frame itself, through setNativeProps() or a re-render of the wrapper alone, so the component that owns the value never re-renders; with the native driver, JavaScript is not involved per frame at all. BookNest's Add button wraps Pressable, so the button itself can shrink under your finger and spring back:

src/anim/AddButton.tsx: a Pressable that springs when pressed (excerpt)TSX
// Pressable's style can now take Animated values, driven natively
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
// ...inside AddButton:
  const springTo = (toValue: number) =>
    Animated.spring(scale, { toValue, speed: 40, bounciness: 12, useNativeDriver: true })
      .start();
  return (
    <AnimatedPressable onPress={onPress} onPressIn={() => springTo(0.9)}
      onPressOut={() => springTo(1)} accessibilityRole="button"
      style={{ transform: [{ scale }], backgroundColor: '#1565c0', borderRadius: 18,

Call createAnimatedComponent() at module scope, never in a render function, or every render creates a new component type and remounts the button. Pass a plain style object, not the ({ pressed }) => ... callback of Press States, so the wrapper can see the animated values.