Skip to content

이름으로 의도 전달하기

이름만 보고 동작을 예측할 수 있어야 합니다. 주체, 방향, 동사가 일관되면 코드를 읽는 비용이 줄어듭니다.

1. 이름은 동작의 주체와 맥락을 드러내자

좋지 않은 예시

tsx
// 타이머에 의해 자동으로 접힌다는 의도였지만,
// "타이머가 접힌다"로 읽힌다.
const [isTimerCollapsed, setIsTimerCollapsed] = useState(false);

문제

isTimerCollapsed는 "타이머가 접힌 상태"로 읽힌다. 실제 의도는 "타이머에 의해 자동으로 접힌 상태"인데, 이름의 주체가 달라지면 동작 예측이 완전히 달라진다.

좋은 예시

tsx
// "자동으로 접힌 상태" — 주체가 명확하다.
const [isAutoCollapsed, setIsAutoCollapsed] = useState(false);

2. boolean은 같은 방향으로 맞추자

좋지 않은 예시

tsx
const [isAutoCollapsed, setIsAutoCollapsed] = useState(false);
const [isGuideExpanded, setIsGuideExpanded] = useState(false);

// collapsed는 true = 접힘, expanded는 true = 펼쳐짐
// 머릿속에서 방향을 뒤집어야 한다
const isCollapsed = isAutoCollapsed && !isGuideExpanded;

문제

isAutoCollapsed(true=접힘)와 isGuideExpanded(true=펼쳐짐)가 섞이면, 조합할 때마다 머릿속에서 방향을 뒤집어야 한다.

좋은 예시

tsx
const [isAutoCollapsed, setIsAutoCollapsed] = useState(false);
const [isManuallyCollapsed, setIsManuallyCollapsed] = useState(true);

// 둘 다 collapsed 기준 — 바로 읽힌다
const isCollapsed = isAutoCollapsed || isManuallyCollapsed;

같은 기준으로 맞추면 조건문이 자연어로 읽힌다.

3. 부정형 이름을 피하자

좋지 않은 예시

tsx
const [isNotVisible, setIsNotVisible] = useState(true);

// 이중 부정 — "보이지 않는 게 아닐 때"???
if (!isNotVisible) {
  return <Banner />;
}

const isDisabled = !hasPermission && !isAdmin;

// "비활성화가 아닐 때" = "활성화될 때"... 머리가 아프다
if (!isDisabled) {
  handleSubmit();
}

문제

부정형 이름은 조건문에서 이중 부정을 만든다. !isNotVisible은 "보이지 않는 게 아닐 때"로 읽히며, 의도를 파악하려면 두 번 생각해야 한다.

좋은 예시

tsx
const [isVisible, setIsVisible] = useState(false);

if (isVisible) {
  return <Banner />;
}

const isEnabled = hasPermission || isAdmin;

if (isEnabled) {
  handleSubmit();
}

긍정형으로 쓰면 조건문이 자연어로 읽힌다. !isNotVisible보다 isVisible이 의도가 명확하다.

4. 같은 역할의 함수에는 같은 동사를 쓰자

좋지 않은 예시

tsx
// 전부 API에서 데이터를 가져오는 함수인데, 동사가 제각각
const fetchUserList = async () => { ... };
const getCourseDetail = async () => { ... };
const loadPaymentHistory = async () => { ... };
const retrieveRefundInfo = async () => { ... };

문제

동사가 섞이면 "각각 다른 동작인가?"라는 의문이 생긴다. get은 동기 계산? fetch는 네트워크? load는 캐시? 같은 역할인데 다른 동사를 쓰면 읽는 사람이 불필요한 구분을 시도하게 된다.

좋은 예시

tsx
const getUserList = async () => { ... };
const getCourseDetail = async () => { ... };
const getPaymentHistory = async () => { ... };
const getRefundInfo = async () => { ... };

동사를 통일하면 "같은 종류의 함수"라는 것이 이름만으로 전달된다.