최근 다른 사람이 설계한 코드를 수정하면서
특정 로직 이전에 안내창을 띄우고, 확인 버튼의 클릭 여부에 따라 이후 로직을 진행하도록 코드를 수정해야 했습니다.
보통, 그리고 이전에 제가 프로젝트를 설계할 때에는 항상 Alert용 모달을 전역 context에서 제어하도록 프로젝트를 설계한 뒤,
핸들러 함수 내에서 Alert 모달의 버튼에 이후 로직을 심었었습니다.
아래처럼요.
const onClickSubmit = () => {
...
contextModal.open({
title: '정보를 저장하지 않고 이동할까요?',
content:'내용',
buttons: [
{
text: '취소',
isCancel: true,
},
{
text: '저장 안함',
onClick: () => {
callback(); // 로직 실행
contextModal.close();
},
},
],
});
...
}
핸들러 -> 함수 -> 또 로직이 들어가는 형태라 살짝 코드가 길어지긴 하지만, 굉장히 편하게 로직들을 작성할 수 있었습니다.
그런데 이번에도 위 방식처럼 로직을 추가하자니
1. 다른 모든 비슷한 코드도 변경할 수 없을텐데 이 로직 하나 넣자고 전역 설계를 바꾸기 껄그러웠고
2. Alert모달을 띄운 순간 함수를 return 시키고 Alert 모달 내부 다른 핸들러에 또 같은 이후 로직을 추가하자니 똑같은 코드가 두개가 생기는 것이 좀 걸렸습니다.
그래서 이전에 팀원이 공유해 준 React 환경에서 특정 로직을 비동기로 멈추는 방법을 공유해 준 것이 떠올라 해당 로직을 찾았고,
이를 좀 더 쉽게 사용하기 위해 아래처럼 Hooks를 만들었습니다.
import { useCallback, useState } from 'react';
export const useYieldLogic = <T,>() => {
const [resolve, setResolve] = useState<(v: T) => void>();
const startYield = useCallback(() => {
return new Promise((resolve) => {
setResolve(() => resolve);
});
}, []);
const endYield = useCallback(
(v: T) => {
resolve?.(v);
},
[resolve],
);
return {
startYield,
endYield,
};
};
그리고 로직을 추가했습니다.
// 이전 함수
const onClickSubmit = () => {
// 조회 API 호출로직
...
}
const {endYield, startYield} = useYieldLogic();
// 변경함수
const onClickSubmit = async() => {
if (isPrecation) {
openPrecationModal();
await startYield(); //
}
// 조회 API 호출로직...
}
const onClickPrecautionConfirm = () => {
endYield(true); // 여기서 전달한 인자를 startYield 에서 return받습니다.
closePrecationModal();
}
이렇게 작성하니 깔끔하게 중간 분기처리 로직만 추가할 수 있었습니다.
또한 핸들러 내에서 제어권을 넘겨 자연스럽게 흐름도 파악되고, 동일한 조회 API로직을 두 번이나 쓸 필요도 없어졌습니다.
이전에 JS DeepDive를 읽을 때 yield개념에 대해 잘 몰랐는데, 이렇게 핸들러 로직 내에서 제어권을 넘겨 yield 개념에 대해 좀 더 이해할 수 있게 되었습니다.
앞으로 단순히 서버 API호출할 때 뿐 만 아니라 Client 환경에서 더 유연하게 비동기 로직을 활용해보면 좋을 듯 합니다.
'Front End' 카테고리의 다른 글
간이 에디터 만들기 + 라이브러리 배포 (1) | 2024.10.20 |
---|---|
Next14에서 shallowRoute 사용하기 + usePagination 구현하기 (0) | 2024.10.01 |
useCheckboxHandler로 체크박스 일관성있게 처리하기 (1) | 2024.10.01 |
Custom File Input 처리시 파일이 변경 되지 않는 에러 (0) | 2024.10.01 |
전역 로딩으로 Sekeleton UI도 처리하기 (0) | 2024.10.01 |