Reanimated ve Paylaşılan Değerleri Kurma
react-native-reanimated paketini kurun, Babel eklentisini ekleyin, useSharedValue ile paylaşılan değerler oluşturun ve bunları useAnimatedStyle kullanarak canlandırılmış stillere bağlayın.
Reanimated ve Paylaşılan Değerleri Kurma, CoddyKit'te ücretsiz bir React Native Academy dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, React Native Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. React Native Academy kursu toplamda 4 dersten oluşur.
Bu dersin bazı bölümleri henüz çevrilmemiş olup İngilizce olarak gösterilmektedir.
Why Reanimated Exists
React Native Reanimated is a more powerful animation library that goes beyond what the built-in Animated API can achieve. While the Animated API moves animation config to native once and runs it there, Reanimated lets you run arbitrary JavaScript-like logic — called worklets — directly on the UI thread, frame by frame.
This enables gesture-driven animations where the animation responds in real time to finger position, impossible with the Animated API's pre-configured approach. Reanimated 3 is the current version and is the foundation of React Native Gesture Handler's smooth interactions.
Installing react-native-reanimated
Install Reanimated from npm, then add the Babel plugin to babel.config.js. The Babel plugin transforms worklet functions at build time so they can run on the UI thread. Without the plugin the library will silently fail at runtime.
For Expo managed workflow, the library must be compatible with your SDK version. Check the Reanimated compatibility table before installing. After installation you must rebuild the native app — Reanimated cannot be added via OTA update.
// Terminal:
// npx expo install react-native-reanimated
// babel.config.js:
module.exports = {
presets: ['babel-preset-expo'],
plugins: ['react-native-reanimated/plugin'],
};
// IMPORTANT: Reanimated plugin must be listed LASTuseSharedValue: The Reanimated Primitive
useSharedValue is Reanimated's equivalent of Animated.Value. It creates a value that is shared between the JavaScript thread and the UI thread, and can be read and written from worklets running on the UI thread without crossing the bridge.
Unlike useState, writing to a shared value does NOT trigger a React re-render. Instead, it directly updates the animated style on the UI thread. This is what enables smooth gesture tracking — updating position 60+ times per second without React involvement.
import { useSharedValue } from 'react-native-reanimated';
import { useEffect } from 'react';
export default function MyComponent() {
const offset = useSharedValue(0);
const opacity = useSharedValue(1);
// Read the value: offset.value
// Write to it: offset.value = 100
}useAnimatedStyle: Connecting Values to Styles
useAnimatedStyle creates a style object that is recalculated on the UI thread whenever any shared value it reads changes. You pass a worklet function that returns a style object, reading shared values with .value. Connect the returned style to a ReanimatedView (imported as Animated.View from Reanimated).
This is the bridge between shared values and the visible UI. The style function runs on the UI thread, so it has zero impact on React rendering or the JavaScript thread.
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';
export default function Box() {
const offset = useSharedValue(0);
const animatedStyles = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
}));
return <Animated.View style={[styles.box, animatedStyles]} />;
}withTiming and withSpring Animations
Instead of calling Animated.timing on a shared value, you assign it the return value of withTiming or withSpring. These are animation functions that drive the shared value toward a target value over time, evaluated on the UI thread.
Assigning offset.value = withTiming(100) starts a smooth timing animation. Assigning offset.value = withSpring(100) starts a spring. This assignment syntax is simpler than the Animated API's imperative .start() pattern.
import { useSharedValue, withTiming, withSpring } from 'react-native-reanimated';
const offset = useSharedValue(0);
// Trigger a timing animation:
function moveRight() {
offset.value = withTiming(200, { duration: 500 });
}
// Trigger a spring:
function springRight() {
offset.value = withSpring(200, { damping: 15, stiffness: 100 });
}Animating Opacity and Scale
Opacity and scale shared values work exactly the same way — create a shared value, build an animated style with useAnimatedStyle, and assign animation functions to the value to trigger transitions. Multiple shared values can be combined in a single useAnimatedStyle.
The key advantage over the Animated API is that the worklet function in useAnimatedStyle runs inline with gesture events on the UI thread, enabling perfectly smooth real-time tracking.
const scale = useSharedValue(1);
const opacity = useSharedValue(0);
const style = useAnimatedStyle(() => ({
opacity: opacity.value,
transform: [{ scale: scale.value }],
}));
// Animate on press:
function press() {
scale.value = withSpring(0.9);
opacity.value = withTiming(0.7, { duration: 150 });
}
function release() {
scale.value = withSpring(1);
opacity.value = withTiming(1, { duration: 150 });
}useAnimatedStyle Worklet Rules
The function passed to useAnimatedStyle is a worklet — it runs on the UI thread, not the JavaScript thread. This means it cannot access JavaScript closures, imported modules, or React state directly. It can only access shared values and primitive constants captured at definition time.
Reanimated's Babel plugin transforms the worklet function to make it UI-thread safe. If you violate these rules, you will see cryptic runtime errors. When in doubt, test with a simple transformation before adding complexity.
const offset = useSharedValue(0);
const MULTIPLIER = 2; // primitives captured OK
// CORRECT: only reads sharedValue and primitive
const style = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value * MULTIPLIER }],
}));
// WRONG: accessing React state would throw
// const [reactState] = useState(0);
// const badStyle = useAnimatedStyle(() => ({
// opacity: reactState, // cannot read React state in worklet
// }));Running Reanimated with Expo Go
Reanimated requires the native module to be compiled into the app binary. In Expo managed workflow, this means you need a development build (created with npx expo run:android or npx expo run:ios) rather than the standard Expo Go app, which does not include Reanimated's native module.
An easy alternative is using Expo's development client (expo-dev-client), which is a customizable Expo Go that includes your own native modules. Install it, rebuild, and scan the QR code to get a development environment that supports Reanimated.
// Install expo-dev-client for Reanimated support:
// npx expo install expo-dev-client
// npx expo run:ios (or run:android)
// Then in babel.config.js ensure:
module.exports = {
presets: ['babel-preset-expo'],
plugins: ['react-native-reanimated/plugin'], // must be last
};Chaining Animations with withSequence
Reanimated provides withSequence and withRepeat to compose animations directly in the value assignment, without the separate Animated.sequence or Animated.loop objects. The syntax is more concise and functional.
withRepeat accepts an animation, a repeat count (−1 for infinite), and a boolean to reverse direction. withSequence chains multiple animation phases in order.
import { withTiming, withSpring, withSequence, withRepeat } from 'react-native-reanimated';
// Shake animation: left, right, center
offset.value = withSequence(
withTiming(-10, { duration: 100 }),
withTiming(10, { duration: 100 }),
withTiming(0, { duration: 100 })
);
// Pulse animation (infinite):
opacity.value = withRepeat(
withTiming(0.3, { duration: 600 }),
-1, // repeat forever
true // reverse each cycle
);Reading Shared Values vs React State
An important mental model: shared values are not React state. Writing to offset.value does not cause a re-render. The UI updates via animated styles directly. If you need to synchronize a shared value with React state (e.g., to render conditional JSX), use useAnimatedReaction or runOnJS to call a React state setter from the UI thread.
Understanding this boundary — Reanimated lives outside React's render cycle — is the key to using it effectively without introducing bugs.
import { useAnimatedReaction, runOnJS } from 'react-native-reanimated';
const [isVisible, setIsVisible] = React.useState(true);
const opacity = useSharedValue(1);
// React to shared value changes on JS thread:
useAnimatedReaction(
() => opacity.value,
(current) => {
if (current === 0) runOnJS(setIsVisible)(false);
}
);Reanimated vs Animated API Summary
When to use each animation system:
- Animated API — Simple entrance/exit animations, opacity fades, pre-configured sequences. Lower learning curve, ships with React Native, sufficient for most apps.
- Reanimated — Gesture-responsive animations, real-time tracking, complex interactive physics. Required when animation must respond to live gesture position frame by frame.
Many production apps use Animated API for simple UI transitions and Reanimated only for gesture-driven components like swipeable cards, bottom sheets, and drag-and-drop.
Quick Check
Test your understanding of React Native Mobile Development concepts from this lesson.
Lesson Recap
In this lesson you learned: useSharedValue creates a value shared between the JS and UI threads for zero-bridge-overhead animations, useAnimatedStyle connects shared values to component styles via a UI-thread worklet, and withTiming and withSpring are assigned to sharedValue.value to start animations. Next up we explore worklets and how they enable complex gesture logic running entirely on the UI thread.
Sıkça Sorulan Sorular
“Reanimated ve Paylaşılan Değerleri Kurma” dersi ücretsiz mi?
Evet — “Reanimated ve Paylaşılan Değerleri Kurma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve React Native Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. React Native Academy kursu toplamda 4 dersten oluşur.
“Reanimated ve Paylaşılan Değerleri Kurma” dersinde ne öğreneceğim?
react-native-reanimated paketini kurun, Babel eklentisini ekleyin, useSharedValue ile paylaşılan değerler oluşturun ve bunları useAnimatedStyle kullanarak canlandırılmış stillere bağlayın. React Native Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
React Native Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te React Native Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.
“Reanimated ve Paylaşılan Değerleri Kurma” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu React Native Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her React Native Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Reanimated ve Paylaşılan Değerleri Kurma
- Worklet'ler ve UI İş Parçacığında Kod Çalıştırma
- Gesture Handler ile Kaydırma ve Sürükleme Hareketleri
- Yakınlaştırma ve Döndürme Hareketleri