React Native: Animated 네임스페이스

nearworld·2023년 6월 5일
0

react-native

목록 보기
1/1

리액트 네이티브에서 슬라이드 버튼을 구현하기 위해 웹의 리액트처럼 translateX 기능이 있는지 궁금하여 찾아보니 Animated 네임스페이스가 리액트 네이티브에서 애니메이션을 담당한다는 것을 발견했다.

아래는 애니메이션에 관련된 함수나 클래스들을 묶어놓은 네임스페이스다.

// node_modules/react-native/Libraries/Animated/Animated.d.ts
export namespace Animated {
  export const timing: () => CompositeAnimation;
}

타입스크립트 파일(.ts)에서 namespace를 작성할 경우 자바스크립트로 컴파일되면 namespaceIIFE가 된다. 하지만 위 코드는 Typescript Definition file .d.ts 확장자를 가지는 파일에서 작성되므로 컴파일 시 아예 날아가기 때문에 자바스크립트에서는 존재하지 않는 코드가 된다.

const timing: () => CompositeAnimation;

위 문법은 .d.ts Typescript Definitions 파일에서만 가능한 문법이고 .ts 에서는 const는 초기화없이 선언될 수 없다고 나온다.

const timing = () => CompositeAnimation;

원래 타입스크립트 파일인 .ts에서는 함수를 위처럼 초기화한다.

위에 나온 timing 함수는 애니메이션이 진행되는 시간(duration)을 설정할 수 있게 해준다.
그리고 애니메이션에 사용될 스타일 값을 지정하여 값의 변경을 통해 애니메이션을 구현하게 해준다.

useEffect(() => {
  Animated.timing(buttonAnim, {
    toValue: 100,
    duration: 500,
    useNativeDriver: true
}, []);

toValue, duration, useNativeDriver 3가지 속성이 사용되었다.

  export const timing: (
    value: AnimatedValue | AnimatedValueXY,
    config: TimingAnimationConfig,
  ) => CompositeAnimation;

위에 timing 함수의 인자 타입을 보면 value, config가 있는 것을 볼 수 있는데 timing함수의 1번째 파라미터인 valueuseRef 훅스를 써서 초기 애니메이션 값을 지정해주는데 사용한다.

const buttonAnim = useRef(new Animated.Value(0)).current;
// 1번째 인자 buttonAnim이 들어가 있다.
Animated.timing(buttonAnim, config);

value 파라미터는 Animated 네임스페이스 이름 바로 아래에 정의되어 있다.

export namespace Animated {
  type AnimatedValue = Value;
  type AnimatedValueXY = ValueXY;
}

Value는 클래스이고 Animated 네임스페이스 내부에 등록되어 있다.

export namespace Animated {
  class Value extends AnimatedWithChildren {
    constructor(value: number, config?: AnimatedConfig | null);
  }
}

buttonAnimAnimated.Value 클래스의 인스턴스다.
constructor를 확인해보면 2번째 파라미터로 config?가 등록되어 있고 그 타입이 AnimatedConfig인데 이 타입을 보면

interface AnimatedConfig {
  readonly useNativeDriver: boolean;
}

useNativeDriver를 사용해도 되고 안해도 되게 설정해놨는데 이 useNativeDriver는 리액트 네이티브에서 requestAnimationFrame함수를 사용하여 매 프레임마다 애니메이션 업데이트를 할 때 리액트 네이티브에서 업데이트 한 후 브릿지를 통해 네이티브 코드로 업데이트 값을 전달하는게 아니라 매 프레임마다 업데이트하는 기능을 네이티브 코드 영역에서 수행하게 하여 매 프레임마다 브릿지로 업데이트 값을 전달하는 과정을 제거하여 애니메이션을 최적화하게 해준다.

공식 문서 출처: https://reactnative.dev/blog/2017/02/14/using-native-driver-for-animated

다시 코드로 와서 Value 클래스의 생성자 함수에 인자값으로 useNativeDriver를 넣어주면 아래와 같이 쓸 수 있다.

const buttonAnim = useRef(new Animated.Value(0, { useNativeDriver: true })).current;

공식 문서에서는 new Animated.Value() 생성자 함수를 사용할 때, 첫번째 인자인 value 값만 설정하는 것을 보여주고 있고 두번째 인자인 useNativeDriver는 설정하지 않고 있다. 프로젝트에서 useNativeDriver를 추가해보니 buttonAnim이 스타일에 등록되어 있는 Animated.View 컴포넌트 자체가 기기 화면에서 사라지는 현상을 발견했다.

어떤 이슈가 있는지는 더 확인해보려고 한다.

그리고 useNativeDrivertiming 함수의 두번째 인자로 들어가는 config 객체에도 설정해줄 수 있다.

Animated.timing(buttonAnim, {
  toValue: 100,
  duration: 500,
  useNativeDriver: true
});

timing 함수에서는 useNativeDriver 설정을 무조건 해줘야한다.true값이면 네이티브 코드에서 프레임마다 애니메이션 업데이트를 실시하겠다는 의미로 애니메이션 성능을 최적화한다고 한다.

다음 블로그에서는 buttonAnim.interpolate() 함수와, useNativeDriverValue()의 두번째 인자에 적용할 경우 발생하는 문제에 대해 살펴봐야겠다.

profile
깃허브: https://github.com/nearworld

0개의 댓글