현재 Next.js로 예술 작품을 보여주는 프로젝트를 진행 중인데
보여지는 그림이 달라지면 끊어지는 느낌을 받는다. 사용자 경험을 위해서
개선이 필요하다고 생각이 들었고 찾아본 결과 framer-motion을 사용하는 것이 좋을거 같기에 사용하게 되었다.
UI가 끊어지는 문제점 발생
// MCQView.tsx
const MCQView = ({ attribute, currentAttributeIndex, handelNextMCQ }: MCQReaderViewProps) => {
// ...
const handleImageClick = (answerId: string) => {
if (!isSubmitted) {
// setSelectedIndex(index);
handleReaderSelectAnswer(answerId);
}
};
// TODO 틀렸을 경우 어떻게 할지 의논 필요
const handleTryAgain = () => {
console.log(`isSubmitted: ${isSubmitted}`);
cleatSubmitState();
handelNextMCQ();
};
return (
// display size 마다 minHeight을 정하여 깜빡임 형상 방지 (모바일 크기만 신경쓰면 됨)
<div className="p-4 rounded-md shadow bg-ggrimBeige2" style={{ minHeight: '744px' }}>
<h3 className="text-xl font-bold text-gray-800 mb-6">{question}</h3>
<motion.div
key={currentAttributeIndex}
initial={{ opacity: 0, x: 50 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -50 }}
// transition={{ duration: 1.0 }}
transition={{
duration: 0.7, // 애니메이션이 총 걸리는 시간
delay: 0.3, // 처음 애니메이션 delay
delayChildren: 0.3,
}}
>
{errorMessage && <ErrorMessage message={errorMessage} />}
<div className="grid md:grid-cols-2 gap-4 sm:grid-cols-1">
{displayPaintings.map((painting, index) => (
<div
key={painting.id}
className={`flex flex-col items-center p-4 rounded-md ${
isSubmitted
? painting.id === answerKey
? 'bg-green-300'
: 'bg-red-300'
: 'bg-white'
} shadow-md ${
readerSelectedAnswer === painting.id
? 'border-4 border-primary'
: ''
}`}
onClick={() => handleImageClick(painting.id)}
>
<img
src={painting.image}
alt={`Answer ${index}`}
className={`w-50 h-auto max-h-[250px] max-w-full mb-2 ${
readerSelectedAnswer === painting.id
? 'ring-4 ring-primary'
: ''
}`}
/>
</div>
))}
</div>
</motion.div>
<div className="flex justify-end items-center">
<SubmissionFeedback
isCorrect={isCorrect}
isSubmitted={isSubmitted}
handleSubmit={handleSubmit}
handleHintButtonClick={handleHintButtonClick}
handleClearSubmission={handleClearSubmission}
handleNextMCQ={handelNextMCQ}
handelTryAgain={handleTryAgain}
showHintButton={false}
/>
</div>
</div>
);
};
framer-motion을 사용하면 될거라는 생각에 적용 방법과 사용 법을 공부를 하였다. 하지만 근본적인 원인은 랜더링 중 state값이 변화되면서 자식 component의 크기가 작아져서 발생하는 문제 였다.
좀 더 문제의 근본적인 원인을 파악하는 연습이 필요함을 느꼈다
(framer-motion을 사용하는게 부드럽게 전화되기에 삭제하지 않았다, )