안녕하세요 트리플랩(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;