간단한 과제 소개
- 포켓몬 데이터 목록을 이용하여 나만의 포켓몬을 추가/삭제할 수 있다.
- 포켓몬 상세 정보를 확인할 수 있다.
사진이 잘 안보여서 버튼이 잘 안보일 수도 있는데 사진 아래 빨간색으로 보이는게 버튼이다. 이번 프로젝트에서 버튼 종류라고 해봐야 검은색, 빨간색 2종류가 있다. 근데 고작 2개의 조건처리를 하는데도 묘한 불편함을 느꼈다(가독성이 특히). 그러다 찾은게 styled-components의 {css} 라이브러리인데 내가 느끼던 불편함을 딱 알맞게 해소해줄 수 있는 녀석이었다.
💡 기존 styled-components의 조건 처리
일단 기존의 `styled-components` 로 조건에 따른 스타일을 변화하려면 다음과 같이 작성해야한다. `styled` 내부에서 삼항연산자를 사용하거나, 함수를 만들던지, 객체를 만들어서 매핑을 시켜준다던지.. 그 중에 그나마 편한 방법으로 쓰고 있었다.
일단 기존 코드들을 확인해보자.
📍 삼항연산자
<StBtn type={'warn'}>
{text}
</StBtn>
const StBtn = styled.button`
background-color: ${props => props.type === 'warn' ? 'red' : 'white'};
color: ${props => props.type === 'warn' ? 'white' : 'black'};
border: none;
padding: 3px 5px 3px 5px;
border-radius: 4px;
`;
문제점
조건으로 처리하는 속성이 2개만 있어도 복잡하고 보기 싫게 생겼다. 그래서 함수로 분리해보았다.
📍 함수에서 조건 처리 (1) - 모든 속성마다 함수 정의
/* 생략 */
const getBgColor = (type) =>{
switch(type){
case 'warn':
return 'red';
default:
return 'white'
}
}
const getColor = (type) => {/* 생략 */}
const StBtn = styled.button`
background-color: ${props => getBgColor(props.type)};
color: ${props => getColor(props.type)};
border: none;
padding: 3px 5px 3px 5px;
border-radius: 4px;
`;
뭐 대충 이렇게 사용하던가 해야한다. 개인적으로 삼항 연산자보다는 쪼~끔 더 괜찮게 생긴 것 같다.
문제점
하지만 같은 타입인데도 필요한 속성마다 함수를 전부 정의하고, 호출하는건 꽤나 불필요한 작업이라고 생각한다. 그래서 이번에는 하나의 함수에서 타입별로 분기가 필요한 모든 속성을 반환하도록 합쳐보았다.
📍 함수에서 조건 처리 (2) - 하나의 함수에서 전부 반환
const getButtonStyles = (type) => {
switch (type) {
case 'back':
return {
backgroundColor: 'black',
color: 'white',
};
default:
return {
backgroundColor: 'red',
color: 'white',
};
}
};
const StBtn = styled.button`
${({ type }) => {
const styles = getButtonStyles(type);
return `
background-color:${styles.backgroundColor};
color:${styles.color};
`;
어처피 공통 변수 type으로 분기를 처리하니 하나의 함수에서 backgroundColor, color 를 전부 반환하도록 변경했다. 개인차가 있겠지만 이전 코드들에 비해서는 깔끔해졌다고 생각이 든다. 특히 type 별 속성에 대한 스타일을 하나의 블록안에서 처리가 가능해졌다는게 가장 큰 장점이 아닐까 싶다.
그래도 초보 개발자의 시선에서 코드가 팍 하고 바로 읽히지는 않는 것 같다. 따라서 styled-components의 `css` 라이브러리를 함께 import해서 변경해보았다.
💡 styled-components의 {css} 라이브러리 사용
import styled, { css } from 'styled-components';
const COLORS = {
warn: css`
background-color: red;
color: white;
`,
default: css`
background-color: black;
color: white;
`,
};
const StBtn = styled.button`
${(props) => props.colorStyle}
border: none;
padding: 3px 5px 3px 5px;
border-radius: 4px;
`;
const Button = ({ text, type = 'default', id, action }) => {
const colorStyle = COLORS[type];
return (
<StBtn colorStyle={colorStyle}>{text}</StBtn>
);
};
코드가 정말 많이 깔끔해졌다. 사용법도 간단하다.
- css를 import한다.
- 객체 형태로 type에 대한 map(객체)을 만들어준다.
- styled에서 반환하면 별도의 속성지정하지 않아도 알아서 바로 적용된다.
📍 변경 목적
- 과제를 시작하기전부터 `styled-components`를 대충 배워 대충 쓰고 있었는데 처음 만난 순간부터 가독성이 별로 좋지 않다고 느껴졌었다. (익숙하지 않아서 그럴수도..)
- 근데 아무리 봐도 고작 2개의 타입, 2개의 속성을 변경하는건데도 코드의 길이나 가독성이 매우 나쁘다고 생각했다.
- 하지만 `css` 라이브러리를 쓰면 우리에게 친숙한 css 문법을 그대로 가져가면서 `styled` 부분의 코드도 매우 짧게 해결할 수 있어서 바로 적용해보았다.
'프로젝트 > 개인프로젝트' 카테고리의 다른 글
[테일윈드 클래스 변경] - 개인 프로젝트 (LOL) #리팩토링 ⚙️ (0) | 2024.11.01 |
---|---|
🚨 [잘못된 Props 전달] - 개인 프로젝트 (LOL) #Next.js #문제 해결 (0) | 2024.10.23 |
[prop drilling 해소] - useContext #리액트 2차 개인과제 리팩토링 (0) | 2024.09.09 |
[강제로 배열길이 늘리기] - Array.prototype.fill #리액트 2차 개인과제 (0) | 2024.09.06 |
[반복되는 코드 줄이기] - Object.values, keys #리액트 1차 개인과제 (0) | 2024.09.05 |