1. JSX props의 true 생략
- props 자체가 true 값이기 때문에
={true}
안 줘도 됨 (false는 ={false}로 명시해야)
Bad
return (
<Navbar showTitle={true} />
);
Good
return(
<Navbar showTitle />
)
2. 삼항연산자 사용하기
- if-else보다 삼항연산자를 쓰면 코드도 줄일 수 있고 가독성도 올라간다.
Bad
const { role } = user;
if (role === ADMIN) {
return <AdminUser />
} else {
return <NormalUser />
}
Good
const { role } = user;
return role === ADMIN ? <AdminUser /> : <NormalUser />
3. switch 말고 객체에서 O(1)로 가져오기
- switch문은 case를 하나씩 확인하며 내려가므로 O(N)의 시간 복잡도
- 객체에서 key로 바로 가져오면 O(1)이 되는 효과!
Bad
const { role } = user;
switch(role) {
case ADMIN:
return <AdminUser />
case EMPLOYEE:
return <EmployeeUser />
case USER:
return <NormalUser />
}
Good
const { role } = user;
const components = {
ADMIN: AdminUser,
EMPLOYEE: EmployeeUser,
USER: NormalUser,
};
const Component = components[role];
return <Component />;
4. Fragment 쓰기
- 아무 기능이 없는 div는 Fragment로 바꿔주면 브라우저에서 따로 DOM을 생성하지 않는다.
Bad
return (
<div>
<Component1 />
<Component2 />
<Component3 />
</div>
)
Good
return (
<>
<Component1 />
<Component2 />
<Component3 />
</>
)
5. 렌더링되는 JSX 안에 함수 넣지 않기
- 한 줄 짜리 코드를 밖으로 빼는 게 더 어지러워보여도 빼야 한다.
- 렌더링 내부 로직은 최대한 간결하게 유지하는 게 좋기 때문이다.
Bad
return (
<button onClick={() => dispatch(ACTION_TO_SEND_DATA)}>
This is a bad example
</button>
)
Good
const submitData = () => dispatch(ACTION_TO_SEND_DATA)
return (
<button onClick={submitData}>
This is a good example
</button>
)
6. Memo 적재적소에 활용하기
- 리액트의 최적화는 대부분 '리렌더링'에 관한 문제이다.
- React.memo를 사용하여 불필요한 컴포넌트의 리렌더링을 막을 수 있다.
Bad
- count 변수를 ChildrenComponent가 아닌 부모 컴포넌트의 button에서만 쓰고 있다.
- 하지만 count가 바뀌면서 ChildrenComponent도 매번 리렌더링된다.
import React, { useState } from "react";
export const TestMemo = () => {
const [userName, setUserName] = useState("Sheryl");
const [count, setCount] = useState(0);
const increment = () => setCount((count) => count + 1);
return (
<>
<ChildrenComponent userName={userName} />
<button onClick={increment}>Increment</button>
</>
);
};
const ChildrenComponent =({ userName }) => {
console.log("rendered", userName);
return <div>{userName}</div>;
};
Good
- ChildrenComponent를 메모이제이션(memo)해주면 관련 없는 state가 변경되었을 때 리렌더링되지 않는다.
import React, { useState } from "react";
const ChildrenComponent = React.memo(({userName}) => {
console.log('rendered');
return <div> {userName}</div>;
})
7. CSS를 JS 안에 넣자 (CSS-in-JS 사용)
- 컴퓨터는 JS를 파싱하는 것보다 CSS를 파싱하는 것이 더 힘들다.
Bad
- CSS 파일을 분리해서 인라인 + 클래스명으로 스타일을 지정한 상태
// CSS FILE
.body {
height: 10px;
}
// JSX
return <div className='body'></div>
Good
- JSX 바깥에서 자바스크립트 객체로 CSS를 선언하고 JSX에 삽입
- 이것도 Bad 스타일처럼 인라인 스타일을 사용했기 때문에 그냥 CSS-in-JS(예: styled-components)를 사용하는 게 좋을 듯 하다.
const bodyStyle = {
height: "10px"
}
return <div style={bodyStyle}></div>
8. 객체 디스트럭쳐링 사용하기
- 이것도 코드가 한 줄 더 늘어나지만 Best Practice에 속한다.
Bad
return (
<>
<div>{user.name}</div>
<div>{user.age}</div>
<div>{user.profession}</div>
</>
)
Good
const { name, age, profession } = user;
return (
<>
<div>{name}</div>
<div>{age}</div>
<div>{profession}</div>
</>
)
9. 문자열 props는 중괄호가 필요 없다
Bad
return(
<Navbar title={"My Special App"} />
)
Good
return(
<Navbar title="My Special App" />
)
10. JSX에서 JS 코드 제거하기
- 이것도 JSX에서 함수를 밖으로 빼 주는 것과 동일하다.
- JSX 내부 코드는 최대한 간결하게!
Bad
return (
<ul>
{posts.map((post) => (
<li
onClick={event => console.log(event.target, 'clicked!')}
key={post.id}
>
{post.title}
</li>
))}
</ul>
);
Good
const onClickHandler = (event) => {
console.log(event.target, 'clicked!');
}
return (
<ul>
{posts.map((post) => (
<li key={post.id} onClick={onClickHandler}>{post.title}</li>
))}
</ul>
);
11. 템플릿 리터럴 사용하기
- 문자열을 '+'로 연결하는 것보다 템플릿 리터럴이 더 가독성이 좋다.
Bad
const userDetails = user.name + "'s profession is" + user.proffession
return (
<div> {userDetails} </div>
)
Good
const userDetails = `${user.name}'s profession is ${user.proffession}`
return (
<div> {userDetails} </div>
)
12. import 순서 일관성 있게
- 일관성은 '예측 가능성'이다.
- import 문이 여러 줄일 때 해당 파일에서 어떤 것이 import가 되었는지 확인하기 편하도록 예측 가능한 순서와 한 줄 띄우기를 적당히 사용한다.
Bad
import React from 'react';
import ErrorImg from '../../assets/images/error.png';
import styled from 'styled-components/native';
import colors from '../../styles/colors';
import { PropTypes } from 'prop-types';
Good
- 보통 많이 사용하는 import문 순서
- 프레임워크 내장(built-in): 'react', 'next/head' 등
- 외부 패키지: 'styled-components' 등
- 내부 파일: '../../assets/images/error.png' 등
- 이 순서 간 import문 사이에 한 줄씩 띄우기
import React from 'react';
import { PropTypes } from 'prop-types';
import styled from 'styled-components/native';
import ErrorImg from '../../assets/images/error.png';
import colors from '../../styles/colors';
13. 암묵적 return (화살표 함수 return문 축약)
- 화살표 함수일 때 1줄 짜리 return 문은 중괄호와 return 키워드 생략 가능
- 객체를 리턴할 때는 '()' 사용으로 축약 가능
Bad
const add = (a, b) => {
return a + b;
}
const getObj = () => {
return { a: key, b: value }
}
Good
const add = (a, b) => a + b;
const getObj = () => ({ a: key, b: value });
14. 컴포넌트 네이밍 케이스 (Pascal vs. Camel)
- 컴포넌트는 무조건 파스칼, 나머지는 카멜 케이스
Bad
import reservationCard from './ReservationCard';
const ReservationItem = <ReservationCard />;
Good
- 컴포넌트(
<ReservationCard />
)만 파스칼로, 나머지는 카멜 케이스로
import ReservationCard from './ReservationCard';
const reservationItem = <ReservationCard />;
15. 컴포넌트 props 이름에 예약어(키워드) 사용하지 말기
Bad
- style은 원래 기본적인 브라우저 태그에 사용하는 키워드
<MyComponent style="dark" />
<MyComponent className="dark" />
Good
- 개발자 자체 커스텀 키워드 사용하기 (예: 'variant')
<MyComponent variant="fancy" />
16. JSX props에만 쌍따옴표 (나머지는 홑따옴표)
Bad
<Foo bar='bar' />
<Foo style={{ left: "20px" }} />
Good
- JSX의 props 값에만 쌍따옴표("") 사용하기
<Foo bar="bar" />
<Foo style={{ left: '20px' }} />
17. '컴포넌트'를 넘기는 props는 파스칼 케이스로
Bad
<Component
UserName="hello"
phone_number={12345678}
/>
Good
<MyComponent
userName="hello"
phoneNumber={12345678}
Component={SomeComponent}
/>
18. return 문의 여러 줄인 JSX는 '()'로 묶기
Bad
- '()'로 감싸주지 않고 작성해서 JSX 형태가 이상함
return <MyComponent variant="long">
<MyChild />
</MyComponent>;
Good
return (
<MyComponent variant="long">
<MyChild />
</MyComponent>
);
19. 컴포넌트에 children이 없으면 self-closing 태그 사용
Bad
<SomeComponent variant="stuff"></SomeComponent>
Good
<SomeComponent variant="stuff" />
20. 함수 이름 앞에 언더바('_') 쓰지 말기
Bad
const _onClickHandler = () => {}
Good
const onClickHandler = () => {}
21. img 태그에 alt 꼭 추가 + alt에 'picture'나 'image' 넣지 않기
- img 태그라면 어차피 스크린 리더가 읽을 때 '이미지'라고 인지한 상태
- alt에 'picture'나 'image' 단어를 넣으면 중복적인 의미가 된다.
Bad
// alt 태그를 안 씀
<img src="hello.jpg" />
// alt 텍스트에 'picture'라는 단어 포함
<img src="hello.jpg" alt="Picture of me rowing a boat" />
Good
- alt 텍스트에는 'picture'나 'image'라는 단어를 넣을 필요가 없다.
<img src="hello.jpg" alt="Me waving hello" />
참고 자료
21 Best Practices for a Clean React Project