React

[React] framer-motion staggerChildren 사용

hid1 2023. 3. 29. 15:28

framer-motion의 staggerChildren은 variants를 사용할시 자식 컴포넌트 애니메이션의 시차를 둘 수 있다. 

예를 들어 stargeChildren이 0.01이면 첫 번째 자식이 0초, 두 번째 자식이 0.01, 세 번째 자식이 0.02 지연된다.

const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: {
      staggerChildren: 0.5
    }
  }
}

const item = {
  hidden: { opacity: 0 },
  show: { opacity: 1 }
}

return (
  <motion.ol
    variants={container}
    initial="hidden"
    animate="show"
  >
    <motion.li variants={item} />
    <motion.li variants={item} />
  </motion.ol>
)

 

나의 경우 서버에서 받아온 데이터를 map으로 돌려 각 아이템이 각각 0.5씩 간격을 두고 애니메이션이 되길 바랬지만 적용이 되지 않는 문제가 생겼다.

const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: {
      staggerChildren: 0.5
    }
  }
}

const item = {
  hidden: { opacity: 0 },
  show: { opacity: 1 }
}


return (
  <motion.ul variants={container} initial="hidden" animate="show">
  {
    dataList?.map((data) => (
      <motion.li variants={item} key={data.id}>{data.content}</motion.li>
    ))
  }
  </motion.ul>
)

 

이를 해결하기 위해 useAnimationControls() hook을 사용하였다. 이 훅은 수동으로 애니메이션을 트리거할 수 있도록 도와주는 훅이다. 반환된 controls를 해당 컴포넌트에 넣고, useEffect를 통해 dataList가 바뀌게 되면 애니메이션이 시작될 수 있도록 start() 메소드를 사용하였다. 작성 후 데이터가 바뀔 떄마다 애니메이션이 적용되었다.

 

 const controls = useAnimationControls();
 
 useEffect(() => {
    controls.start("show");
  }, [dataList, controls]);

 
 return (
  <motion.ul variants={container} initial="hidden" animate={controls}>
  {
    dataList?.map((data) => (
      <motion.li variants={item} key={data.id}>{data.content}</motion.li>
    ))
  }
  </motion.ul>
)

 

 

 

반응형