MENU

React Native Worklet’ler Nasıl Çalışır

Animasyonların değerini hepimiz göze güzel görünen hoş bir uygulama yaptığımızda anlayabiliyoruz. Ancak, hayattaki herşey gibi bu da göründüğü kadar kolay değil. İşte burada yardımımıza Reanimated Kütüphanesi koşuyor.

October 22, 2024

Türkçe

Bugün sizlere bu kütüphanenin nasıl kullanılacağını, bununla birlikte nerede ve nasıl kullanılması gerektiğini tanıtacağım. Daha fazla beklemeden kısa bir açıklama ile giriş yapalım.

Worklet’ler nedir?

Hepimizin bildiği gibi React Native içinde 3 ana ve 1 adet yeni mimariler için oluşturulan thread yapıları bulunuyor. Buna dayalı olarak worklet yapılarını UI thread veya JSI üzerinden çalışan fonksiyonlar olarak özetleyebiliriz. Bu, bize performansta yaşanan darboğazdan kurtulmamızı ve akıcı bir UI animasyon deneyimi yaşamamızı sağlıyor.

Worklet’ler neden var?

Worklet’lerin amacı, JavaScript kod parçalarını tanımlayıp çalıştırdığımızda onların UI thread üzerinden olaylara tepki vermesini ve UI tarafının güncellenmesini sağlamaktır.

Nasıl çalışırlar?

Bir worklet fonksiyonunu oluşturmak gayet basittir. Sadece bir fonksiyon tanımlayıp en başına 'worklet' direktifini yerleştirin.

Aşağıdaki örneği incelediğinizde, worklet fonksiyonunu UI thread üzerindeki boxOffset değerlerini güncellemek için kullandığımızı görebilirsiniz. Ayrıca useAnimatedStyle hook uygulanarak kutu bileşenimiz için tasarımlarımızı belirliyoruz.

Not: Yazının devamında useAnimatedStyle ve useSharedValue açıklanacaktır.

const boxOffset = useSharedValue(0);

function moveBox() {
'worklet';
// Bu UI thread üzerinde çalışıyor.
    boxOffset.value = withSpring(boxOffset.value === 0 ? 200 : 0);
}

const boxAnimatedStyles = useAnimatedStyle(() => {
// Bu da ayrıca UI thread üzerinde çalışıp üstine stil objesi oluşturuyor.
    return {
        transform: [{ translateX: boxOffset.value }],
    };
});

function handleButtonPress() {
  runOnUI(moveBox)();
}

return (
 <View
   style={{
     width: '100%',
   }}
   >
 <Animated.View
   style={[
     {
       marginTop: 100,
       width: 80,
       height: 80,
       backgroundColor: '#b58df1',
       borderRadius: 10,
     },
     boxAnimatedStyles,
   ]}
 />
   <TouchableOpacity
     style={{
       marginTop: 30,
       backgroundColor: '#782aeb',
       padding: 15,
       borderRadius: 10,
     }}
     onPress={handleButtonPress}
   >
     <Text
       style={{
         fontSize: 18,
         textAlign: 'center',
         color: '#fff',
       }}
     >
       Move Box
     </Text>
   </TouchableOpacity>
 </View>
)

Nasıl çalıştığını merak edenler için:

Burada yazılanları UI thread üzerinden özellikle çağırmak zorunda değilsiniz. Hatta normal bir fonksiyon olarak da çağırılabilirler. Aslında, console.log kullandığımız zaman kendisi UI thread bağlamında tanımlanmış olmuyor; onun yerine, React Native JavaScript bağlamının sağladığı bir metoda referans olarak geçiyor. Bu şu anlama geliyor, örneklerdeki gibi console.log kullanıldığı vakit bunlar React Native thread üzerinden yürütülüyor.

Worklet’ler iç içe olabilir. Ek olarak, birbirlerinden argümanlar alabilirler. Bu durumda UI thread üzerinden eş zamanlı olarak çağrılırlar.

function childWorklet() {
  "worklet";
  return "alt worklet";
}

function parentWorklet() {
  "worklet";
  let childWorkletValue = childWorklet()
  console.log("Üst worklet sahip olduğu", childWorkletValue)
}

Bu normal bir fonksiyon olarak da kullanılabilir. Uygulaması oldukça basit.

function regularChildFunction() {
  return "sıradan alt fonksiyon";
}

function parentWorklet() {
  "worklet";
  let regularChildFuncValue = regularChildFunction()
  console.log("Üst worklet sahip olduğu", regularChildFuncValue)
}

Nasıl çağrıldıklarına ek olarak, tanımlandıkları yerdeki bağlamı da yakalayabilirler.

Unutmamalıyız ki worklet’lere argüman verebiliyoruz. Bu, özünde fonksiyon olmalarından kaynaklanan bir durumdur. Hadi size bir örnekle olayı gösterelim!

const sharedValue = useSharedValue(0);

function updateValue(value: number) {
  "worklet";
  console.log("Paylaşılan değer: ", value);
}

function handleButtonPress() {
  runOnUI(updateValue)(sharedValue.value + 10)
}

return (
  <Button title="Update Shared Value" onPress={handleButtonPress} />
)

Ne zaman ihtiyacımız olur?

Worklet’leri kullanmak için birçok sebep vardır. Örnek olarak bir SVG animasyonu çalıştırmak isteyebilirsiniz, ancak bunun JS thread üzerinde ağır bir işlem olabileceği ihtimalini verebiliriz. Buna bir çözüm olarak worklet’leri kullanarak animasyonları UI thread üzerinde çalıştırıp akıcı bir animasyon deneyimi elde edebilirsiniz.

Worklet direktifine dayalı diğer Reanimated API yapıları

UseAnimatedStyle: Bir View veya başka bir bileşen için değişiklik gerektiğinde bu hook yapısına sık sık ihtiyaç duyarız. Bu hook, worklet direktifine dayalı olduğundan ötürü, worklet direktifini yazmak zorunda değilsiniz. Bu özellikle worklet’i dış değerlere bağlı olarak çalıştırdığımızda kullanışlı hale gelir (react states gibi).

UseSharedValue: Bu, Reanimated animasyonlarıyla yaygın olarak kullanılan bir hook’tur. Amaçları veri depolama, tepkisellik ve animasyonlarla çalışmak olarak sıralanabilir. value değerini kullanarak veri okuyup yazabilirsiniz. Tepkisellik, value değeri ile sağlanıyor. UI thread ile nasıl çalıştığına gelince, her ne zaman useSharedValue ile ilgili bir güncelleme olursa, worklet o değişikliğe abone olur ve onu UI thread kısmında uygular. Aşağıdaki örnek ile nasıl çalıştığını inceleyebilirsiniz.

const boxWidth = useSharedValue(300);

const boxAnimatedStyles = useAnimatedStyle(() => {  
  // Animasyonlu kutu stili boxWidth değeri güncellendiği zaman kendini güncelleyecektir
  return {
      width: boxOffset.value,
  };
});
function handlePress() {
  // Paylaşımlı değerlerimizi güncellemek için worklet kullanmak zorunda değiliz.
  // React Native thread üzerinden direkt güncelleyebilirsiz.
  boxWidth.value = Math.random() * 300
}
return (
  <>
    <Animated.View style={[boxAnimatedStyles, boxStyles]} />
    <Button title="Random Box Width" onPress={handlePress} />
  </>
)

Worklet’lerin sadece UI thread üzerinde çalışan JavaScript kodları olduklarını unutmamalıyız. Bu, bize aynı bileşenlerin içinde yaptığımız gibi useAnimatedStyle içine de JavaScript kodu yerleştirme imkanı verir. Tek fark, JSX yerine React Native stili döndürmesidir.

Sonuç

Bu yazımızda sizelere worklet’leri, ne zaman kullanılması gerekildiğini ve projelerinizde nasıl kullanmanız gerektiğini açıkladım. Ayrıca worklet tabanlı bazı diğer API’leri de sizlere açıkladım.

Nihayetinde doğru aleti kullanmak sizlerin elinde. Burada önerim projeniz için en iyi olan ne ise ona göre seçim yapmanız.

Sizlerle sonraki yazılarımda görüşmek üzere, kendinize iyi bakın ve kendinizi her zaman geliştirin. 👋

React-Native

Worklets

Animation

Ömer Ayhan

Front-End Developer

HQ

Maslak Mah. AOS 55. Sok.
B Blok Apt. No: 4 / 542
Sarıyer / İstanbul 34475

R&D

Üniversite Mah. Sarıgül Sok.
No: 37 / 1 İç Kapı No: 91
Avcılar / İstanbul 34320

© 2024 - All rights reserved

HQ

Maslak Mah. AOS 55. Sok.
B Blok Apt. No: 4 / 542
Sarıyer / İstanbul 34475

R&D

Üniversite Mah. Sarıgül Sok.
No: 37 / 1 İç Kapı No: 91
Avcılar / İstanbul 34320

© 2024 - All rights reserved

HQ

Maslak Mah. AOS 55. Sok. B Blok Apt. No: 4 / 542
Sarıyer / İstanbul 34475

R&D

Üniversite Mah. Sarıgül Sok. No: 37 / 1 İç Kapı No: 91 Avcılar / İstanbul 34320

© 2024 - All rights reserved