☀️Siang
Mobile Development

React Native Reanimated 3

TOKEN

Tutorial komprehensif Reanimated 3 — shared values, worklets, gesture handler, layout animations, spring physics, dan scroll-based animation

Artikel: React Native Reanimated Artikel: React Native Reanimated


1. Pengenalan Reanimated 3

React Native Reanimated 3 adalah library animasi canggih yang menjalankan animasi di UI thread (bukan JS thread). Ini menghasilkan animasi yang sangat halus pada 60fps bahkan saat JS thread sibuk.

Reanimated 3 membawa perubahan signifikan: worklet system baru yang lebih cepat, shared values yang lebih fleksibel, dan integrasi mendalam dengan react-native-gesture-handler.

Arsitektur Reanimated 3
⚛️
JS Thread
React Logic
State Updates
🔗
Shared Values
Bridge antara
JS & UI Thread
🎨
UI Thread
Animations
60fps rendering

1.1 Instalasi

Bash — Instalasi

# Install Reanimated 3
npm install react-native-reanimated

# Untuk Expo (SDK 50+)
npx expo install react-native-reanimated

# Tambahkan babel plugin
# babel.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['react-native-reanimated/plugin'],
};
⚠️ Babel Plugin

Plugin Babel Reanimated HARUS menjadi item terakhir dalam daftar plugins. Jika tidak, worklet compilation akan gagal.

 ad-slot-wide"> 

2. Shared Values

useSharedValue adalah state yang dapat diakses oleh kedua thread — JS dan UI. Perubahan shared value tidak memicu re-render React, sehingga sangat efisien untuk data animasi.

JavaScript — useSharedValue

import { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
import { View, Button } from 'react-native';

function AnimatedBox() {
  // Shared value — bisa diakses di JS & UI thread
  const offset = useSharedValue(0);

  // Animated style — berjalan di UI thread
  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateX: offset.value }],
  }));

  return (
    
      
      

2.1 Perbandingan Shared Value vs State

AspekuseStateuseSharedValue
ThreadJS ThreadUI Thread
Re-renderYaTidak
AnimasiTerputus-putusHalus 60fps
Gesture responseAda delayInstant
Use caseUI stateAnimasi & gesture


3. Worklets

Worklet adalah fungsi JavaScript yang dikompilasi dan dieksekusi di UI thread. Ini memungkinkan logika kompleks berjalan tanpa memblokir UI.

JavaScript — Worklet Functions

'use worklet';

// Worklet function — runs on UI thread
function customEasing(t) {
  'worklet';
  return t * t * (3 - 2 * t); // smoothstep
}

// Menggunakan worklet dalam animation
const animatedStyle = useAnimatedStyle(() => {
  'worklet';
  const progress = withTiming(1, { duration: 500 });
  return {
    opacity: progress,
    transform: [{ scale: customEasing(progress) }],
  };
});

// Worklet untuk logging di UI thread
const style = useAnimatedStyle(() => {
  'worklet';
  console.log('Running on UI thread!');
  // runOnJS untuk memanggil JS function dari worklet
  runOnJS(trackEvent)('animation_complete');
  return { opacity: 1 };
});
📋 Kapan Menggunakan Worklet?

Gunakan worklet untuk logika yang harus berjalan di UI thread: kalkulasi animasi, response gesture, dan interpolasi kompleks. Untuk operasi async seperti network call, tetap di JS thread.



4. Integrasi Gesture Handler

Reanimated 3 terintegrasi sempurna dengan react-native-gesture-handler untuk membuat gesture-driven animation yang responsif.

JavaScript — Gesture + Reanimated

import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, {
  useSharedValue, useAnimatedStyle, withSpring,
} from 'react-native-reanimated';

function DraggableBox() {
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);
  const prevX = useSharedValue(0);
  const prevY = useSharedValue(0);

  const pan = Gesture.Pan()
    .onStart(() => {
      prevX.value = translateX.value;
      prevY.value = translateY.value;
    })
    .onUpdate((e) => {
      translateX.value = prevX.value + e.translationX;
      translateY.value = prevY.value + e.translationY;
    })
    .onEnd(() => {
      // Snap back to origin
      translateX.value = withSpring(0, { damping: 15 });
      translateY.value = withSpring(0, { damping: 15 });
    });

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: translateX.value },
      { translateY: translateY.value },
    ],
  }));

  return (
    
      
    
  );
}

4.1 Composing Gestures

JavaScript — Gesture Composition

// Gabungkan pan + pinch + rotation
const pan = Gesture.Pan().onUpdate((e) => {
  translateX.value = e.translationX;
  translateY.value = e.translationY;
});

const pinch = Gesture.Pinch().onUpdate((e) => {
  scale.value = e.scale;
});

const rotation = Gesture.Rotation().onUpdate((e) => {
  rotate.value = e.rotation;
});

// Jalankan bersamaan
const composed = Gesture.Simultaneous(pan, pinch, rotation);


  



5. Layout Animations

Reanimated 3 mendukung layout animations bawaan untuk enter, exit, dan layout transition — tanpa kode animasi manual.

JavaScript — Layout Animations

import Animated, {
  FadeIn, FadeOut, SlideInRight, Layout,
  BounceIn, ZoomOut,
} from 'react-native-reanimated';

function AnimatedList({ items }) {
  return (
     (
        
          {item.title}
        
      )}
    />
  );
}

// Custom entering animation
const CustomEnter = () => {
  'worklet';
  return {
    initialValues: { transform: [{ scale: 0 }], opacity: 0 },
    animations: {
      transform: [{ scale: withSpring(1) }],
      opacity: withTiming(1, { duration: 300 }),
    },
  };
};

// Menggunakan custom animation

  Custom Enter!



6. Spring Physics & Timing

Reanimated menyediakan berbagai animation function berbasis fisika: withSpring, withTiming, withDecay, dan withDelay.

JavaScript — Spring & Timing

import Animated, {
  withSpring, withTiming, withDecay, withDelay,
  useSharedValue, useAnimatedStyle, Easing,
} from 'react-native-reanimated';

// Spring animation — berbasis fisika
offset.value = withSpring(100, {
  damping: 10,         // Redaman (default: 10)
  stiffness: 100,      // Kekakuan (default: 100)
  mass: 1,             // Massa (default: 1)
  overshootClamping: false,  // Clamp di target
  restDisplacementThreshold: 0.01,
  restSpeedThreshold: 2,
});

// Timing animation — berbasis kurva
opacity.value = withTiming(1, {
  duration: 500,
  easing: Easing.bezier(0.25, 0.1, 0.25, 1),
});

// Decay animation — deselerasi natural
velocityX.value = withDecay({
  velocity: 200,        // Kecepatan awal
  clamp: [-200, 200],   // Batas bawah & atas
  deceleration: 0.997,  // Faktor deselerasi
});

// Delay + sequence
offset.value = withDelay(
  500, // Delay 500ms
  withSpring(200)
);
FungsiTipeKarakteristik
withSpringFisikaRealistis, ada bounce/overshoot
withTimingKurvaPresisi, kurva halus
withDecayDeselerasiScroll momentum, swipe
withDelayKomposerMenunda animasi berikutnya
💡 Tips Performa

Gunakan withSpring untuk interaksi user (gesture, tap) karena terasa natural. Gunakan withTiming untuk animasi UI yang presisi seperti fade dan slide transition.



7. Scroll-based Animations

JavaScript — Scroll Animations

import Animated, {
  useAnimatedScrollHandler, useAnimatedStyle, interpolate, Extrapolation,
} from 'react-native-reanimated';

function ParallaxHeader() {
  const scrollY = useSharedValue(0);

  const scrollHandler = useAnimatedScrollHandler({
    onScroll: (e) => {
      scrollY.value = e.contentOffset.y;
    },
  });

  const headerStyle = useAnimatedStyle(() => ({
    transform: [{
      translateY: interpolate(
        scrollY.value,
        [0, 300],
        [0, -150],
        Extrapolation.CLAMP,
      ),
    }],
    opacity: interpolate(
      scrollY.value,
      [0, 200],
      [1, 0],
      Extrapolation.CLAMP,
    ),
  }));

  return (
    
      
        Parallax Header
      
      
        {/* Content */}
      
    
  );
}


8. Best Practices

PraktikAlasan
Gunakan shared values untuk data animasiTidak trigger re-render React
Minimalkan runOnJS callsBridge JS↔UI ada overhead
Gunakan Layout AnimationsKurangi kode animasi manual
Hindari membuat worklet baru di renderBisa menyebabkan re-compilation
Gunakan gesture-handler langsungIntegrasi native lebih dalam


Quiz Pemahaman

Pertanyaan 1: Di thread mana animasi Reanimated 3 berjalan?

a) JS Thread
b) Background Thread
c) UI Thread
d) Main Thread

Pertanyaan 2: Apa fungsi useSharedValue?

a) Mengelola state React biasa
b) State yang bisa diakses JS & UI thread tanpa re-render
c) Menyimpan data ke AsyncStorage
d) Mengelola theme aplikasi

Pertanyaan 3: Apa itu 'worklet' di Reanimated?

a) Plugin Babel
b) Fungsi yang dikompilasi dan dieksekusi di UI thread
c) Native module Android
d) Testing utility

Pertanyaan 4: Fungsi animasi apa yang berbasis fisika dan memiliki bounce?

a) withTiming
b) withDecay
c) withSpring
d) withDelay

Pertanyaan 5: Mengapa plugin Babel Reanimated harus item terakhir?

a) Agar kompatibel dengan React 18
b) Agar worklet compilation bekerja dengan benar
c) Untuk mengurangi bundle size
d) Agar support Hermes engine

← SebelumnyaKembali ke Beranda Selanjutnya →Lihat Kategori
🔍 Zoom
100%
🎨 Tema