useSharedValue vs useDerivedValue

useSharedValue

useSharedValue는 애니메이션의 초기값을 설정할 때나 UI Thread에서 자주 변경되는 값을 저장하기 위한 상태입니다.

초기 애니메이션 상태나 좌표, 크기, 회전값을 저장합니다.

import { useSharedValue } from 'react-native-reanimated';

function App() {
  const sv = useSharedValue(100);

  // read a shared value
  console.log(sv.value);

  // and modify it
  sv.value += 50;
}

React에서 useState와 같은 역할을 한다고 생각할 수 있지만 큰 차이를 갖는데요.

React-Native는 JS코드를 Android나 Ios와 같은 실제 네이티브 컴포넌트로 전환하게 됩니다.

useState를 사용할 경우 setState -> React Render -> React Native Bridge/Fabric -> Native View -> 그리기 과정을 거칩니다.

하지만 useSharedValue는 기기 내부에 있는 UI Thread에서 값을 저장하고, 이를 직접 처리합니다.

sharedValue.value 변경 -> (UI Thread에서 바로 처리) -> Native View 변경 -> 화면 그리기 과정을 거칩니다.

useSharedValue는 UI Thread에서, useState는 JS Thread에서 관리하기 때문에 애니메이션과 상태 관리는 각각의 함수에서 처리하는 것이 좋습니다.

이를 통해 애니메이션의 상태 값이 운영을 담당하는 JS Thread와 분리되기 때문에 JS Thread가 바쁘더라도 애니메이션이 끊기지 않고 동작할 수 있습니다.

// 1. React가 count.value 값이 변경되어도  렌더링을 하지 않음
const count = useSharedValue(0);

<Text>{count.value}</Text>

// 2.  React가 count.value 값이 변경될 때  애니메이션을 변경함
const style = useAnimatedStyle(() => ({
  transform: [{ translateX: count.value }],
}));

useDerivedValue

useDerivedValue는 애니메이션의 값을 계산할 때 주로 사용합니다.

shared Value 값을 만들 때 useMemo처럼 계산식을 써서 새로운 값을 만드는 형태입니다.

useDerivedValue는 주로 SharedValue를 기반으로 계산식을 통해 새로운 값을 만들 때 사용합니다.

useDerivedValue는 useSharedValue와 마찬가지로 UI Thread 내부에서 실행됩니다.

const x = useSharedValue(100);

const doubled = useDerivedValue(() => {
  return x.value * 2;
});

위의 두 함수는 애니메이션을 담당하는 상태값을 관리하기 위해 사용되며, JS Thread가 아닌 UI Thread 내부에서 사용됩니다.

따라서 애니메이션 중에도 JS Thread와 관계없이 부드럽게 값을 계산할 수 있으며, 계산된 값은 다른 애니메이션 스타일이나 Worklet에서 바로 사용할 수 있습니다.

** 참고

https://docs.swmansion.com/react-native-reanimated/docs/core/useSharedValue

https://docs.swmansion.com/react-native-reanimated/docs/core/useDerivedValue