미라클 메모리전체코드
const [emotion, setEmotion] = useState("");
const handleClickEmote = (emotion) => {
setEmotion(emotion);
};
...
<Wrapper>
{emotionList &&
emotionList.map((list) => (
<EditEmotion
key={list.emotion_id}
{...list}
onClick={handleClickEmote}
isSelected={list.emotion_id === emotion}
/>
))}
</Wrapper>
Emotion Item들을 누를때 마다 색상이 변경이 되는것을 구현하고자한다. 이때 emotionList의 코드는 아래와같다.
export const emotionList = [
{
emotion_id: 1,
emotion_img: process.env.PUBLIC_URL + `/assets/emotion1.png`,
emotion_descript: "완전 좋음",
},
...
{
emotion_id: 5,
emotion_img: process.env.PUBLIC_URL + `/assets/emotion5.png`,
emotion_descript: "끔찍함",
},
];
emotionList를 매핑하여 emotionItem들을 만들어낸다. 이때 emotion_id값을 활용하면 isSelected라는 props를 넘겨줌으로써 스타일링을 할 수 있다. 이때 핵심은 바로 아래부분이다.
isSelected={list.emotion_id === emotion}
isSelected props는 불리언값을 props로 전달한다. 그리고 EmotionItem은 전달받은 불리언 값을 통해서 className을 조건부로 정할 수 있다.
<EmotionItem
onClick={() => onClick(emotion_id)}
className={isSelected ? `on_${emotion_id}` : "off"}
>
<EmotionImg src={emotion_img} />
<EmotionText>{emotion_descript}</EmotionText>
</EmotionItem>
만약 isSlected값이 True라면 className은 전달받은 emotion_id값과 합쳐진 className을 얻을 수 있다. 그리고 만약 값이 다르다면 classname은 off가 더해진다.
여기서 중요한 것은 handleClickEmote함수다. EditEmotion 컴포넌트에 onClick이라는 props로 전달된 이 함수는 EditEmotionBox 에 onClick 이벤트로 등록이 된다. 만약 첫 번째에 있는 EditEmotionBox를 클릭하면 무슨 일이 발생할까?
<EmotionItem
onClick={() => onClick(emotion_id)}
className={isSelected ? `on_${emotion_id}` : "off"}
>
...
</EmotionItem>
이벤트가 발생하면서 handleClick 함수에 첫번째 컴포넌트가 전달받았던 id값을 인수값으로 보낸다. 그에따라서 emotion의 상태값이 변경된다.
const [emotion, setEmotion] = useState(3);
이어서 다시 EmotionBox 컴포넌트에 선언되어있는 EditEmotion 컴포넌트에 전달된 isSelected props를 보자