ETC -

Framer Slider part

  • -

안녕하세요 트리플랩(TriplexLab) 입니다.

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map

사실 React에서 key가 변경 하면 위와 같은 코드로 순회하는 로직은 필요가 없어 집니다.

👉 수정 전 코드

<AnimatePresence>
  {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((i) =>
    i === visible ? (
      <Box
        key={i}
        variants={boxVariants}
        initial="invisible"
        animate="visible"
        exit="exit"
      >
        {i}
      </Box>
    ) : null
  )}
</AnimatePresence>

여기서 주의 깊게 봐야할것은 
React js는 key를 바꾸면 component를 re-render를 해준다 입니다!
새로운 component가 생겼다고 생각하는 것 입니다.
그래서 React js는 이전 것을 없에버리고 새 것을 보여주는것이죠!

👉 수정 후 코드

<AnimatePresence>
  <Box
    key={visible}
    variants={boxVariants}
    initial="invisible"
    animate="visible"
    exit="exit"
  >
    {visible}
  </Box>
</AnimatePresence>

👉 전체 코드 공유

import styled from "styled-components";
import { AnimatePresence, motion } from "framer-motion";
import { useState } from "react";

const boxVariants = {
  entry: (isBack: boolean) => ({
    x: isBack ? -500 : 500,
    opacity: 0,
    scale: 0,
  }),
  center: {
    x: 0,
    opacity: 1,
    scale: 1,
    transition: {
      duration: 1,
    },
  },
  exit: (isBack: boolean) => ({
    x: isBack ? 500 : -500,
    option: 0,
    scale: 0,
    transition: {
      duration: 1,
    },
  }),
};

function App() {
  const [visible, setVisible] = useState(1);
  const [isBack, setIsBack] = useState(false);
  const prevPlease = () => {
    setIsBack(true);
    setVisible((prev) => (prev === 1 ? 1 : prev - 1));
  };
  const nextPlease = () => {
    setIsBack(false);
    setVisible((prev) => (prev === 10 ? 10 : prev + 1));
  };

  return (
    <Wrapper>
      <AnimatePresence custom={isBack}>
        <Box
          custom={isBack}
          key={visible}
          variants={boxVariants}
          initial="entry"
          animate="center"
          exit="exit"
        >
          {visible}
        </Box>
      </AnimatePresence>
      <button onClick={prevPlease}>prev</button>
      <button onClick={nextPlease}>next</button>
    </Wrapper>
  );
}

const Wrapper = styled(motion.div)`
  height: 100vw;
  align-items: center;
  background-color: #333;
  display: flex;
  justify-content: center;
  align-items: center;
  button {
    background-color: #fff;
    margin-left: 10px;
  }
`;

const Box = styled(motion.div)`
  width: 400px;
  height: 200px;
  background-color: rgba(255, 255, 255, 1);
  border-radius: 40px;
  position: absolute;
  top: 100px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 28px;
`;

export default App;
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.