부트캠프 개발일지 2023-2024/Bootcamp 생활기록
[7주차] 리액트: 버튼을 눌렀을 때 색 변하게 하기 (styled-components)
whereanna00
2023. 11. 14. 11:15
현재 상황
- <buttonI> 를 map 으로 돌려 총 4개의 버튼이 화면에 랜더링되는 상황
- buttonText 정보와 각각의 아이디가 들어 있는 배열이 선언되어 있음
Task
- 화면을 로딩했을 때, 첫번째 버튼이 눌려져 있어야 함
- 4개 중 버튼은 하나만 누르는 것이 가능함
- 버튼 활성화 시, 배경색이 검정 그리고 글자색이 흰색 비활성화 시, 배경색이 흰색 그리고 글자색이 검정색
해결방법
- 화면을 로딩했을 때, 첫번째 버튼이 눌려져 있어야 함
- 4개 중 버튼은 하나만 누르는 것이 가능함
- 버튼 활성
전체코드 BEFORE
더보기
Button.jsx
import { styled } from 'styled-components';
import React from 'react';
import {useState} from 'react';
import { useEffect } from 'react';
const ButtonBox = styled.div`
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
`;
const ButtonI = styled.button`
width: 100px;
height: 50px;
font-size: 1rem;
font-weight: 500;
border: 1px solid black;
transition: 0.2s ease;
cursor: pointer;
&:hover {
background-color: black;
color: white;
}
`;
// background-color: ${selectedCharacterId === buttonText.id ? 'black' : 'white'};
// background-color: ${setPaulButtonActivated ? 'black' : 'white'};
// color: ${props => props.ButtonActivated ? 'white' : 'black'};
function Button({setPaulLetterShown,setElioLetterShown, setGatsbyLetterShown, setLeeLetterShown})
{
const [selectedCharacterId, SetSelectedCharacterId] = useState(1);
const [buttonText, setButtonText] = useState(
[
{id:1, name: "Paul"},
{id:2, name: "Elio"},
{id:3, name: "Gatsby"},
{id:4, name: "Lee"},
]
);
// 첫화면에 paul 버튼 활성화 세팅
useEffect(()=> {
// setPaulButtonActivated(true);
// setElioButtonActivated(false);
// setGatsbyButtonActivated(false);
// setLeeButtonActivated(false);
setPaulLetterShown(true);
setElioLetterShown(false);
setGatsbyLetterShown(false);
setLeeLetterShown(false);
}, []);
const buttonByNameClickHandler = (item) => {
SetSelectedCharacterId(item.id);
switch (item.name) {
case 'Paul':
setPaulLetterShown(true);
setElioLetterShown(false);
setGatsbyLetterShown(false);
setLeeLetterShown(false);
break;
case 'Elio':
setElioLetterShown(true);
setPaulLetterShown(false);
setGatsbyLetterShown(false);
setLeeLetterShown(false);
break;
case 'Gatsby':
setGatsbyLetterShown(true);
setElioLetterShown(false);
setPaulLetterShown(false);
setLeeLetterShown(false);
break;
case 'Lee':
setLeeLetterShown(true);
setGatsbyLetterShown(false);
setElioLetterShown(false);
setPaulLetterShown(false);
break;
default:
break;
}
}
return (
<ButtonBox>
{buttonText.map((item)=>{
return(
<ButtonI key={item.id} onClick={()=> buttonByNameClickHandler(item) } style={{
backgroundColor: selectedCharacterId === item.id ? "black" : "white",
color: selectedCharacterId === item.id ? "white" : "black",
}}>{item.name}</ButtonI>
);
})}
</ButtonBox>
)
}
export default Button
리펙토링
- <ButtonI> 태그 내에 인라인으로 들어가 있던 조건부 css 를 styled-components 방식에 따라 전역에서 선언되는 <ButtonI> 선언부쪽에 옮김
- 옮기는 과정에서, props 방식을 통해 selectedCharacterId / buttonId 를 <ButtonI> 태그 컴포넌트에 전해줌
- <ButtonI> 선언부 내에서는 동적인 조건부 스타일을 구현하기 위해 백틱안에서 함수요소를 다룰 때 쓰는 ${}로 감싸줌
- () => () 형식으로 이루어지고, 삼항 연산자를 씀
전체코드 AFTER
더보기
Button jsx
import { styled } from 'styled-components';
import React from 'react';
import {useState} from 'react';
import { useEffect } from 'react';
const ButtonBox = styled.div`
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
`;
const ButtonI = styled.button`
width: 100px;
height: 50px;
font-size: 1rem;
font-weight: 500;
border: 1px solid black;
transition: 0.2s ease;
cursor: pointer;
&:hover {
background-color: black;
color: white;
}
background-color: ${(props) => (props.selectedCharacterId === props.buttonId ? 'black' : 'white')};
color: ${(props) => (props.selectedCharacterId === props.buttonId ? 'white' : 'black')};
`;
function Button({setPaulLetterShown,setElioLetterShown, setGatsbyLetterShown, setLeeLetterShown})
{
const [selectedCharacterId, SetSelectedCharacterId] = useState(1);
const [buttonText, setButtonText] = useState(
[
{id:1, name: "Paul"},
{id:2, name: "Elio"},
{id:3, name: "Gatsby"},
{id:4, name: "Lee"},
]
);
// 첫화면에 paul 버튼과 paul letters 활성화 세팅
useEffect(()=> {
setPaulLetterShown(true);
setElioLetterShown(false);
setGatsbyLetterShown(false);
setLeeLetterShown(false);
}, []);
const buttonByNameClickHandler = (item) => {
SetSelectedCharacterId(item.id);
switch (item.name) {
case 'Paul':
setPaulLetterShown(true);
setElioLetterShown(false);
setGatsbyLetterShown(false);
setLeeLetterShown(false);
break;
case 'Elio':
setElioLetterShown(true);
setPaulLetterShown(false);
setGatsbyLetterShown(false);
setLeeLetterShown(false);
break;
case 'Gatsby':
setGatsbyLetterShown(true);
setElioLetterShown(false);
setPaulLetterShown(false);
setLeeLetterShown(false);
break;
case 'Lee':
setLeeLetterShown(true);
setGatsbyLetterShown(false);
setElioLetterShown(false);
setPaulLetterShown(false);
break;
default:
break;
}
}
return (
<ButtonBox>
{buttonText.map((item)=>{
return(
<ButtonI key={item.id} onClick={()=> buttonByNameClickHandler(item) } selectedCharacterId={selectedCharacterId} buttonId={item.id}>{item.name}</ButtonI>
);
})}
</ButtonBox>
)
}
export default Button
728x90
반응형