Code Style Convention

CRM 프로젝트의 Code Style Convention을 정의합니다. 컴포넌트, 페이지 등 UI 코드 작성에 관한 컨벤션을 주로 다룹니다. React 17, Emotion 11을 기준으로 작성하였으며, Emotion의 Styled Component 기능을 주로 활용합니다.

File Naming

컴포넌트 : ~.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 파일을 생성해야할 때 이 규칙을 따릅니다.)

One React Component Per File

한 파일에 하나의 리액트 컴포넌트만 작성합니다. 하지만 State를 별도로 갖지 않거나 순수 컴포넌트인 경우(전역 변수를 참조하지 않고 props만output에 영향을 끼치는 경우) 예외로 합니다.

Styled Component Naming

// 최상위 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>
    )
}

Function Component

// 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>

Class Component