[React] 토글 상태 관리 트러블슈팅💫
발생한 문제 🤦♀️
모든 질문이 동일한 toggle 상태를 공유하여, 한 토글을 클릭하면 모든 토글의 상태가 변경되는 문제가 발생했다.
문제 원인 🤷♀️
toggle 상태가 아래와 같이 전역적으로 관리되어 모든 질문에 동일하게 적용되고 있기 때문이였다.
const [toggle, setToggle] = useState(false);
해결 방안 💁♀️
각 질문의 toggle 상태를 독립적으로 관리하도록 state를 수정하였다. 이를 위해 toggle 상태를 객체로 관리하여 각 질문의 상태를 개별적으로 제어할 수 있도록 하였다.
코드 수정 전
const FrequencyQuestion = () => {
const navigate = useNavigate();
const [toggle, setToggle] = useState(false);
return (
<FrequencyLayout>
<FrequencyBox>
<FrequencyImage
src="images/leftArrow.png"
onClick={() => navigate(-1)}
/>
<FrequencyText>자주 묻는 질문</FrequencyText>
</FrequencyBox>
<QuestionSearch />
{frequencyQuestion.map((item) => {
return (
<FrequencyQuestionList key={item.id}>
<FrequencyQuestionQ>
<FrequencyColorBlue>Q</FrequencyColorBlue>
{item.question}
<FrequencyArrow
src="images/leftArrow.png"
onClick={() => setToggle(!toggle)}
/>
</FrequencyQuestionQ>
{toggle && (
<FrequencyQuestionA>
<FrequencyColorBlue>A</FrequencyColorBlue>
{item.ans}
</FrequencyQuestionA>
)}
</FrequencyQuestionList>
);
})}
</FrequencyLayout>
);
};
export default FrequencyQuestion;
const FrequencyArrow = styled.img`
transform: ${(props) => (props.toggle ? "rotate(180deg)" : "rotate(90deg)")};
`;
코드 수정 후
const FrequencyQuestion = () => {
const navigate = useNavigate();
const [toggle, setToggle] = useState({});
const toggleShow = (id) => {
// prev는 업데이트 이전의 toggles 상태를 나타냄
setToggle((prev) => ({
...prev,
[id]: !prev[id],
}));
};
return (
<FrequencyLayout>
<FrequencyBox>
<FrequencyImage
src="images/leftArrow.png"
onClick={() => navigate(-1)}
/>
<FrequencyText>자주 묻는 질문</FrequencyText>
</FrequencyBox>
<QuestionSearch />
{frequencyQuestion.map((item) => {
return (
<FrequencyQuestionList key={item.id}>
<FrequencyQuestionQ>
<FrequencyColorBlue>Q</FrequencyColorBlue>
{item.question}
{/* toggle 상태를 FrequencyArrow에 전달 */}
<FrequencyArrow
src="images/leftArrow.png"
onClick={() => toggleShow(item.id)}
toggle={toggle[item.id]}
/>
</FrequencyQuestionQ>
{toggle[item.id] && (
<FrequencyQuestionA>
<FrequencyColorBlue>A</FrequencyColorBlue>
{item.ans}
</FrequencyQuestionA>
)}
</FrequencyQuestionList>
);
})}
</FrequencyLayout>
);
};
export default FrequencyQuestion;
// FrequencyArrow에 toggle prop을 추가하고 스타일을 동적으로 적용
const FrequencyArrow = styled.img`
width: 27px;
display: flex;
transform: ${(props) => (props.toggle ? "rotate(270deg)" : "rotate(90deg)")};
position: absolute;
right: 17rem;
cursor: pointer;
`;
댓글남기기