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 () => { ... };

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