CRM 프로젝트의 Code Style Convention을 정의합니다. 컴포넌트, 페이지 등 UI 코드 작성에 관한 컨벤션을 주로 다룹니다. React 17, Emotion 11을 기준으로 작성하였으며, Emotion의 Styled Component 기능을 주로 활용합니다.
컴포넌트 : ~.component.tsx
유틸 : ~.util.ts
Test: ~.test.ts
Hooks: ~.hooks.ts
API : ~.api.ts
페이지 : ~.tsx
Storybook : ~.stories.tsx
Style : ~.style.ts
| ~.style.tsx
(기본적으로 CSS in JS
방식을 따르며, 컴포넌트 파일 내에 style 정의를 함께 합니다. 다만 global style 등 별도 style 파일을 생성해야할 때 이 규칙을 따릅니다.)
한 파일에 하나의 리액트 컴포넌트만 작성합니다. 하지만 State를 별도로 갖지 않거나 순수 컴포넌트인 경우(전역 변수를 참조하지 않고 props만output에 영향을 끼치는 경우) 예외로 합니다.
~Container
: 기능 없이 단순히 Style을 위한 영역을 묶어 줄 때~Text
: Text만을 별도 div로 감싸서 넣고 싶을 때~Modal
, ~CheckBox
등 : 기존 Master Component에 추가 스타일 적용한 컴포넌트MyComponentContainer
(X) → Container
(O) ex2) MyComponentHeaderText
(X) → HeaderText
(O)// 최상위 div wrapper는 Container로 명명합니다.
const Container = styled.div`
display: absoloute;
width: 100%;
height: 100%;
`;
const MyButtonContainer = styled.div`
display: flex;
`;
// 기본 HTML Element가 아닌 경우, 스타일 입힐 컴포넌트를 괄호안에 넣어줍니다.
const MyButton = styled(Button)`
width: 56px;
`;
const HeaderContainer = styled.div`
width: 100%;
height: 40px;
`;
// Text를 별도로 div로 감싸서 넣고 싶을 땐, ~Text로 명명합니다.
const HeaderText = styled.div`
font-size: 15px;
&:hover {
color: blue;
}
`;
// 명확한 child component naming으로 가독성을 높힙니다.
const Header = () => {
return (
<HeaderContainer>
<HeaderText>I'm Header<HeaderText>
</HeaderContainer>
)
}
// Props도 PascalCase!
interface MyComponentProps {
message: string;
}
const MyComponent = ({ message }: MyComponentProps) => <div>{message}</div>;
// 혹은
const MyComponent = (props: MyComponentProps) => {
const { message } = props;
return <div>{message}</div>
}
// inline으로 쓰고 싶다면
const MyComponent = ({message} : {message: string}) => <div>{message}</div>;
return type 없다는 lint는 끌 예정입니다. (JSX.Element로 타입이 자동 추론됩니다)
React.FC 안쓰는 이유? : children 쓰는 컴포넌트에서만 명시적으로 별도 표시하는 게 더 좋다. (참고 : https://velog.io/@namezin/Why-I-dont-use-React.FC)
// children 사용을 별도로 Props에 명시
interface MyComponentProps {
message: string;
children: ReactNode;
}
const MyComponent = ({ message, children }: MyComponentProps) => <div>{children}</div>
// PropsWithChildren을 사용해도 좋습니다.
import { PropsWithChildren } from 'react'
interface MyComponentProps {
message: string;
}
const MyComponent ({ message, children }: PropsWithChildren<MyComponentProps>) => <div>{children}</div>