Q1
props 로 특정한 정수 값을 받고 그 값이 변경될 때 화면에 숫자가 올라가거나 내려가면서 표시되는 애니메이션을 구현하고 싶어요.
A1
AnimatedNumberFramerMotion
컴포넌트를 수정해서, props로 전달된 value
가 변경될 때 화면에 숫자가 올라가거나 내려가면서 표시되도록 만들 수 있습니다.
방법:
motionValue
와useEffect
를 사용하여value
의 변화를 감지.useSpring
으로 부드러운 애니메이션 적용.motion.span
에 숫자가 연속적으로 보이도록useTransform
사용.
코드:
'use client';
import { motion, useMotionValue, useSpring, useTransform } from 'framer-motion';
import { useEffect } from 'react';
const spring = { damping: 5, stiffness: 50, restDelta: 0.001 };
function AnimatedNumberFramerMotion({ value }: { value: number }) {
const motionValue = useMotionValue(value); // motionValue 초기화
const springNumber = useSpring(motionValue, spring);
const transformingNumber = useTransform(springNumber, (x) => Math.round(x));
// value가 변경될 때마다 motionValue에 애니메이션으로 적용
useEffect(() => {
motionValue.set(value);
}, [value, motionValue]);
return (
<motion.span>
{transformingNumber} {/* 실시간으로 변화하는 숫자 표시 */}
</motion.span>
);
}
function FramerMotionAnimateNumberPage() {
const [num, setNum] = useState(0);
// 3초마다 랜덤 숫자 설정
useEffect(() => {
const interval = setInterval(() => {
const newNum = Math.floor(Math.random() * 100); // 0~99 사이의 랜덤 숫자
setNum(newNum);
}, 3000);
return () => clearInterval(interval);
}, []);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
<span>Target Number: {num}</span>
<AnimatedNumberFramerMotion value={num} />
</div>
);
}
export default FramerMotionAnimateNumberPage;
주요 사항 설명:
motionValue.set(value)
useEffect
를 사용해value
가 변경될 때마다motionValue
를 업데이트합니다.useSpring
적용
숫자가 부드럽게 올라가거나 내려가는 애니메이션을 적용했습니다.Math.round
사용useTransform
을 사용해 부동소수점 값을 정수로 변환하여 화면에 표시합니다.
실행 결과:
value
가0
에서3
으로 변경되면 0 → 1 → 2 → 3 순서로 부드럽게 증가합니다.- 반대로
3
에서0
으로 변경되면 3 → 2 → 1 → 0 순서로 감소합니다.
이제 애니메이션이 자연스럽게 숫자의 변화에 따라 표시됩니다. 🚀
Q2
const motionValue = useMotionValue(value);
이 부분은 value 를 받아서 초기화되잖아요? 그러면 부모에서 props 가 바뀔때마다 새로 실행될텐데 useEffect 에서 또 motionValue.set 을 해줘야 하는 이유가 궁금해요.
A2
좋은 질문이에요! const motionValue = useMotionValue(value);
는 value
를 초기값으로 설정하지만, 부모 컴포넌트에서 value
가 변경될 때마다 motionValue
가 새로 설정되지는 않습니다.
이유: useMotionValue
는 상태를 초기화할 때만 실행됩니다.
useMotionValue
는 React의 상태와 비슷한 방식으로 동작하기 때문에, 초기 렌더링 시에만 value
를 초기값으로 설정합니다. 이후 부모에서 value
가 변경되어도 useMotionValue
는 새로 호출되지 않아요.
useEffect
에서 motionValue.set(value)
가 필요한 이유:
motionValue
는 React 상태와 달리 직접 업데이트해줘야 하는 객체입니다. value
가 변경될 때 motionValue
에 반영되도록 motionValue.set(value)
를 호출하는 것입니다.
useEffect(() => {
motionValue.set(value);
}, [value, motionValue]);
이 코드의 역할:
value
가 변경되면motionValue
를 새로운 값으로 업데이트합니다.useEffect
가value
를 감지하고, 애니메이션이 부드럽게 적용될 수 있도록 합니다.
요약:
useMotionValue
는 초기값만 설정하고, 이후 상태 변화는 반영되지 않음.useEffect
에서motionValue.set(value)
를 호출해야 부모에서 받은value
가motionValue
에 반영됩니다.
이렇게 해야 motionValue
가 항상 최신 상태를 유지하면서 애니메이션이 자연스럽게 동작합니다! 😊
'TIL' 카테고리의 다른 글
[241219 TIL] Severless (0) | 2024.12.19 |
---|---|
[241219 TIL] pnpm 장점 (0) | 2024.12.19 |
[241209 TIL] AWS - RDS, EB 에 nest 배포(3) (0) | 2024.12.09 |
[241209 TIL] AWS - RDS, EB 에 nest 배포(2) (0) | 2024.12.09 |
[241208 TIL] AWS - RDS, EB 에 nest 배포(1) (0) | 2024.12.09 |