나오는 코드들은 변형을 준 코드입니다.
/**
* 직접 넘어온 도메인이 있으면 해당 값으로 세팅. 없으면 state 변수에 있는 값으로 세팅.
* value + @ + 도메인값 으로 value 넘김.
*
* @param currentValue
* @param _domain 추가 도메인
*/
const handleChangeEmail = (currentVal: string, _domain?: string): void => {
const currentDomain = _domain || domain;
const emailValue = `${currentVal}@${currentDomain === "direct" ? directDomain.current || "" : currentDomain}`; // 👈 1. 한 눈에 알아보기 어려움
const valid = validate(emailValue);
setValue(currentValue);
// 👇 2. 더 축약할 수 있음.
if (onChange !== undefined) {
onChange(name, emailValue);
}
if (handleChangeValue) {
handleChangeValue(name, { value: emailValue, isValid: valid });
}
};
코드 설명
주석 참고
아쉬웠던 부분
강조하고 싶은 부분은 주석(+ 👈 이모지)으로 추가했다.
일단 한 눈에 알아보기가 매우 어려웠다.
그리고 어떤 state는 useState로 어떤 state는 useRef로 관리했는데, 이런 방식은 코드를 이해하고 관리하는데 더한 어려움을 초래하는 부분이라고 생각했다.
또한 코드를 더 줄여서 가독성을 높일 수 있겠다고 생각했다.
// 👇 한 눈에 알아보기 쉬움
/**
* 새로 받은 값에 맞춰 이메일 주소 형태(emailId + @ + 도메인값) 제작
* (직접 넘어온 도메인이 있으면 해당 값으로 세팅. 없으면 state 변수에 있는 값으로 세팅.) // 👈 주석 및 논리는 동일하게 유지
*
* @param newEmailId
* @param newDomain
* @param newDirectDomain
*/
const constructEmailAddress = (newEmailId?: string, newDomain?: string, newDirectDomain?: string) => {
// 👇 3가지 변수에 동일한 규칙 적용
const currentEmailId = newEmailId ?? emailId;
const currentDomain = newDomain ?? domain;
const currentDirectDomain = newDirectDomain ?? directDomain;
return `${currentEmailId}@${currentDomain === "direct" ? currentDirectDomain : currentDomain}`;
};
/**
* 새로운 형성된 이메일을 필요에 따라 처리
* - 새 값에 맞는 이메일 형식 만들기
* - validation 체크
* - props로 넘겨받은 함수에 값 전달 등
*/
const handleChangeEmail = (newEmail: emailValueType) => {
const newEmailAddress = constructEmailAddress(newEmail); // 👈 [함수 분리] 이메일 컨버팅
const valid = validate(newEmailAddress);
onChange?.(name, newEmailAddress); // 👈 [축약] 옵셔널 체이닝 추가
handleChangeValue?.(name, { value: newEmailAddress, isValid: valid }); // 👈 [축약] 옵셔널 체이닝 추가
};
코드 설명
주석 참고
결과
한 눈에 알아보기 쉽게 변형
Nullish coalescing operator (??)
)constructEmailAddress
)CTO님 및 동료에게 칭찬은 덤 👏
const IndexOfselectedTab = useMemo<TabIndexType>(() => {
for (let i = 0; i < items.length; i++) {
if (router.asPath.includes(encodeURI(items[i].as)) || router.pathname.includes(items[i].link)) {
return i + 1;
}
}
return false;
}, [router.pathname]);
코드 설명과 아쉬웠던 부분
CTO님이 작성하셨었던 기존 코드다.
잘 만드셨지만 아쉬운 부분은 로직을 한 눈에 파악하기 어렵다는 점이 있었다.
결국 조건(if문 내부)에 맞는 index를 찾아 있다면 +1을 하고 없다면 false 처리 한다는 로직인데, js 메소드를 잘만 찾으면 더 가독성 있고 짧은 코드를 만들 수 있겠다는 생각이 들어서 리팩토링을 하게 되었다. (또한 시간적 여유도 있어서 진행했다.)
const IndexOfselectedTab: TabIndexType = useMemo(() => items.findIndex(({ as, href }) => decodeURI(asPath).includes(as) || pathname.includes(href)) + 1 || false, [pathname]);
코드 설명
가독성 ⬆️ (직관적인 js메소드 사용 & 간결해진 코드)
findIndex라는 적절한 메소드를 찾았다.
as나 href 포함되어 있다면 해당 index에 +1을, 아니면 false를 반환하는 로직이다.
전보다 간결해졌을 뿐만 아니라 가독성도 좋아졌음을 알 수 있다.
(CTO님이 감탄하셔서 뿌듯했다.)