본문 바로가기
개발로그/ReactNative

에러가 있는 코드로부터 배운다. React Native Animated 에서의 Value 수정하기(useRef)

by 그리너리디밸로퍼 2023. 2. 1.

<문제가 있는 코드>

export default function App() {
  const [up, setUp] = useState(false);
  // state 가 변경되어 컴포넌트가 re-rendering이 될 때마다 모든 코드가 다시 실행된다.
  // 그래서 21번째 라인이 실행되며 다시 초기값인 Y=0이 된다.
  const Y =  new Animated.Value(0);
  const toggleUp = () => setUp((prev) => !prev);
  const moveUp = () => {
    Animated.timing(Y, {
      toValue: up ? 200 : -200,
      useNativeDriver: true,
      easing: Easing.circle,
    }).start(toggleUp);
  };
  Y.addListener(()=>console.log("Animated State:",Y));
  console.log("Component State:",Y);
  
  return (
    <Container>
      <TouchableOpacity onPress={moveUp}>
        <AnimatedBox
          style={{
            transform: [{ translateY: Y }],
          }}
        />
      </TouchableOpacity>
    </Container>
  );
}

이 코드는 컴포넌트가 다시 렌더링 될 때마다 

const Y = useRef(new Animated.Value(0)).current;

이것이 실행되면서 변수들이 초기값으로 돌아간다.

 

  Y.addListener(()=>console.log("Animated State:",Y));
  console.log("Component State:",Y);

이렇게 각 상태에서의 Y값을 로그로 찍어본다면, Component State 에서의 Y 값은 계속해서 0으로 초기화되는것을 알 수 있다. 이유는 애니메이션이 끝난 뒤 toogleUp이라는 메소드에서 state 값을 변경하고 컴포넌트가 다시 렌더링 되기 때문이다. 이때 렌더링이란 컴포넌트에 있는 코드를 모두 (초기화 까지 포함하여) 다시 실행한다는 의미이기도 하다. 

 

해결방법: 

 

  # before
  const Y = new Animated.Value(0);
  
  # after using useRef
  const Y = useRef(new Animated.Value(0)).current;

useRef 를 사용해서 component가 다시 렌더링 된다고 하더라도 그 value는 초기값으로 돌아가지 않도록 한다.

useRef : The returned object will persist for the full liftime of the component.

useRef 사용법

import {useRef} from "react"

const AnimationValue = useRef(new Animated.Value(0)).current;

 

728x90

댓글