클린코드의 핵심은 의미 있는 변수명을 사용하는 것에서 시작한다. 코드 컨벤션은 팀원 모두가 같은 규칙을 따르도록 해 협업을 원활하게 하고, 코드를 빠르게 이해할 수 있게 한다.
const thisIsVariable = true;
const goToHome = () => {};
사용 위치: 페이지 경로, 폴더명, CSS 클래스 이름 등에 사용
예시:
pages/todo-list/TodoList.tsx
.item-id
사용 위치: JS에서 상수 선언 시 대문자 표현으로 사용
예시:
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000;
사용 위치: 컴포넌트 및 페이지 파일명에 사용
예시:
TodoList.tsx
Detail.tsx
명확하고 구체적인 의미를 담기
Bad:
let a = 1;
Good:
let phoneNumber = '010-1234-5678';
예시:
const isGood = true;
const hasGirlFriend = false;
const loading = true;
Bad:
const todo = [1, 2, 3];
Good:
const todos = [1, 2, 3];
동사로 시작하기
Bad:
const home = () => {};
Good:
const goToHome = () => {};
배열:
const array = [1, 2, 3];
const newArray = [...array];
객체:
const obj = { key: 1 };
const newObj = { ...obj };
배열:
const [state, setState] = useState();
객체:
const ItemComponent = ({ title }) => <span>{title}</span>;
컴포넌트:
const Parent = ({ title, ...rest }) => (
<>
<span>{title}</span>
<Child {...rest} />
</>
);
const Child = ({ content, subTitle }) => (
<>
<span>{content}</span>
<span>{subTitle}</span>
</>
);
함수:
const validBoolean = (...args) => args.every(isTrue => isTrue);
부정 조건은 가독성이 떨어지므로 가능하면 긍정 조건을 사용한다.
// Bad
const isNotBoy = false;
if (!isNotBoy) {}
// Good
const isBoy = true;
if (isBoy) {}
const isBoy = !isNotBoy; // if 문 바로 상단에서 긍정 조건으로 변경
if (isBoy) {}
조건문은 명확한 의미를 담도록 이름을 붙인다.
// Bad
if (name === 'js' && obj.someProperty.title === "sparta" && height < 180) {}
// Good
const isJsTutor = name === 'js' && obj.someProperty.title === "sparta" && height < 180;
if (isJsTutor) {}
복잡한 조건문은 함수로 분리하여 재사용성과 유지보수를 높인다.
// Bad
if (name === 'js' && obj.someProperty.title === "sparta" && height < 180) {}
// Good
const checkThisDataValid = ({ name, title, height }) => {
let result = true;
// 비즈니스 로직
return result;
};
if (checkThisDataValid({ name, title, height })) {}
조건문과 반복문의 중첩이 깊어지지 않도록 주의한다.
Guard Clause(Early Return)를 활용해 깊이를 최소화한다.
// Bad
async function guardClause(userId) {
const user = await getUser(userId);
if (user) {
const orders = await getOrders(user);
if (orders && orders.length > 0) {
const order = orders.find(order => order.value > 100);
if (order) {
console.log(`Found an order from user ${user.id} with value greater than 100: ${order.id}`);
}
}
}
}
// Good
async function guardClause(userId) {
const user = await getUser(userId);
if (!user) return;
const orders = await getOrders(user);
if (!orders || orders.length === 0) return;
const order = orders.find(order => order.value > 100);
if (!order) return;
console.log(`Found an order from user ${user.id} with value greater than 100: ${order.id}`);
}
Object Mapping을 사용해 조건문을 효과적으로 대체한다.
function loginWithKakao() {}
function loginWithGoogle() {}
function loginWithApple() {}
const socialMapper = {
kakao: loginWithKakao,
google: loginWithGoogle,
apple: loginWithApple,
};
const socialLogin = (social) => {
socialMapper[social]();
};
초기값 설정
반환값이 필요한 경우, 명확한 초기값을 설정해 undefined
로 인한 문제를 방지한다.
function calculateTotalPrice(items) {
let totalPrice = 0;
if (!items || items.length === 0) {
return totalPrice;
}
items.forEach(item => {
totalPrice += item.price * item.quantity;
});
return totalPrice;
}
명확하고 읽기 좋은 코드 작성: 함수명을 통해 코드의 의도를 드러내고, 각 함수는 하나의 역할만 수행해야 한다.
단일 책임 원칙 : 하나의 함수는 한 가지 동작만 하도록 설계해야 한다.
( 예: 계산 함수는 add, minus처럼 개별 동작으로 나눈다.)
인수 개수 제한: 함수 인수는 최대 두 개가 적합하며, boolean을 사용하여 조건을 분기하지 않는다.
MyComponent.js)
, 훅(useFetch.js
), 서비스(apiService.js
))/src
/components
/Button
index.js
Button.test.js
/hooks
useFetch.js
/services
apiService.js
위 내용을 활용하면 코드의 가독성과 유지보수성을 크게 향상시킬 수 있다.
아 너무 좋은 정리네요 구웃 ^-^)b