🚗 Div의 컴포넌트화
html의 태그인 div태그를 컴포넌트화 하여 별도의 파일로 분리하는 것은 React의 일반적인 관행이다.
'styled-components'를 사용하여 Div.jsx와 같은 파일에 스타일을 정의하는 이유는 여러가지가 있다.
[Chat GPT]
- 컴포넌트 기반 설계: React는 컴포넌트 기반의 접근 방식을 취하며, 각 컴포넌트는 자체적인 로직과 스타일을 가질 수 있습니다. 이를 통해 재사용 가능하고 독립적인 UI 조각을 생성할 수 있습니다.
- 명확성 및 유지 보수성: 스타일이 해당 컴포넌트와 함께 위치함으로써, 어떤 스타일이 특정 컴포넌트에 적용되는지 쉽게 파악할 수 있습니다. 이는 코드의 가독성을 향상시키고 유지 보수를 용이하게 합니다.
- 스코핑: styled-components를 사용하면 생성된 스타일은 컴포넌트에 자동으로 스코핑되어, 다른 컴포넌트의 스타일과 충돌하지 않습니다. 이는 CSS 클래스명 충돌을 방지하고, 글로벌 스타일에서 발생할 수 있는 예기치 않은 부작용을 최소화합니다.
- 동적 스타일링: styled-components를 통해 props를 사용하여 조건부 스타일링을 쉽게 할 수 있습니다. 이 예에서 ImageDiv는 width, height, border-radius, background-image 등의 스타일을 props를 통해 동적으로 받고 있으며, 이는 컴포넌트를 더 유연하게 만들어 줍니다.
- 코드 분리: 로직과 스타일을 분리함으로써, 개발자는 UI와 관련된 코드에 더 집중할 수 있으며, 디자인 시스템을 구축할 때 일관성을 유지하기 더 쉽습니다.
- 테마 및 디자인 시스템 통합: styled-components는 테마나 디자인 시스템과의 통합을 용이하게 합니다. 전체 애플리케이션에 걸쳐 일관된 스타일을 적용하고, 필요에 따라 테마를 쉽게 변경할 수 있습니다.
이러한 이유로 React 개발자들은 'styled-components'와 같은 CSS-in-JS 라이브러리를 선호하며, 이는 개별 컴포넌트의 스타일을 정의하고 관리하는 효과적인 방법이다.
CSS Flexbox 레이아웃을 활용하여 FlexDiv라는 컴포넌트를 만들어보겠다.
우선 component폴더 아래에 div폴더와 해당 파일을 만들어준다.
index.js파일에서는 Div를 export할 수 있도록 다음과 같이 작성해준다.
export { default as Div } from './Div';
이후 FlexDiv를 작성해주었다.
이렇게 작성하는 이유는 버튼이 아니라 div태그를 이용하여 버튼의 역할을 수행하도록 하기 위해서다.
import styled from 'styled-components';
export const FlexDiv = styled.div`
display: flex;
align-items: center;
box-sizing: border-box;
&::-webkit-scrollbar {
display: none;
}
`;
이제 Header안에서 버튼을 HeaderItem이 해당 기능을 수행할 수 있도록 div를 작성해준다.
const HeaderItem = styled.div`
height: 28px;
padding: 0 16px;
text-align: center;
font-size: 14px;
font-family: 'MediumFont';
cursor: pointer;
`;
이 둘을 활용하여 코드를 작성하면 아래와 같다.
import { LOGO } from 'assets/images';
import { Image } from 'components/img';
import { FlexDiv } from 'components/div/Div';
import { BACK_COLOR2, Q_COLOR } from 'constants/color';
import styled from 'styled-components';
import { useEffect, useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
const HeaderDiv = styled.div`
width: 100%;
box-sizing: border-box;
padding: 20px 80px 0;
`;
const HeaderItem = styled.div`
height: 28px;
padding: 0 16px;
text-align: center;
font-size: 14px;
font-family: 'MediumFont';
cursor: pointer;
`;
const Header = () => {
const [selected, setSelected] = useState('메인');
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
const path = location.pathname;
if (path === '/') {
setSelected('메인');
} else if (path === '/champAnalyze') {
setSelected('챔피언 분석');
} else if (path === '/matchCompare') {
setSelected('경기력 비교');
} else if (path === '/AISuggestion') {
setSelected('AI챔피언 추천');
} else {
setSelected('');
}
}, [location]);
return (
<HeaderDiv>
<Image src={LOGO} alt="LOLPAGO" />
<FlexDiv
style={{
width: '100%',
borderBottom: `1px solid ${BACK_COLOR2}`,
marginTop: '20px',
}}
>
<HeaderItem onClick={() => navigate('/')}>메인</HeaderItem>
<HeaderItem onClick={() => navigate('/champAnalyze')}>챔피언 분석</HeaderItem>
<HeaderItem onClick={() => navigate('/matchCompare')}>경기력 비교</HeaderItem>
<HeaderItem onClick={() => navigate('/AISuggestion')}>AI챔피언 추천</HeaderItem> <span>{selected}</span>
</FlexDiv>
</HeaderDiv>
);
};
export default Header;
실행했을 때의 화면은 아래와 같다.
각각은 버튼아 아니지만 버튼의 역할을 수행하고 있다.
'LOLPAGO > 프론트엔드' 카테고리의 다른 글
[LOLPAGO] 검색 창 구성(1) (0) | 2024.02.29 |
---|---|
[LOLPAGO] React 설치 및 Header 구성 완료(6) (0) | 2024.02.27 |
[LOLPAGO] React 설치 및 Header 구성(4) (0) | 2024.02.26 |
[React] 리액트 훅스(2) - useEffect (0) | 2024.02.23 |
[LOLPAGO] React 설치 및 Header 구성(3) (0) | 2024.02.23 |