문제 상황
AddContactForm에서 폼을 제출한 후 SideSheet를 닫고 싶어서 onClose 함수를 내려줬다.
또, SideSheet 안에 있는 닫기 버튼을 눌러도 사이드시트가 닫히지 않았다.
코드는 아래처럼 되어 있었다:
<SideSheet isOpen={isAddContactOpen} onClose={() => handleClose}>
<AddContactForm onClose={() => handleClose} />
</SideSheet>
분명 handleClose() 함수는 정상적으로 작동하고, 상태도 잘 바뀌는 것 같았는데...
왜 사이드시트가 안 닫히는 걸까?
원인
결론부터 말하면,
onClose={() => handleClose}는 실제 함수를 전달한 게 아니라, 함수를 리턴하는 함수를 전달한 것이었다.
즉, () => handleClose는 handleClose()를 실행하는 게 아니라
그냥 handleClose라는 함수 자체를 리턴만 하고 아무 일도 하지 않게 되는 것이다.
그래서 클릭을 해도 사이드시트가 닫히지 않았다.
해결 방법
onClose에는 실행할 함수 자체를 직접 넘겨야 한다.
즉, 괄호를 없애면 된다.
const handleClose = () => setIsAddContactOpen(false);
<SideSheet isOpen={isAddContactOpen} onClose={handleClose}>
<AddContactForm onClose={handleClose} />
</SideSheet>
이제는 닫기 버튼을 눌러도, 폼 제출 후에도 정상적으로 사이드시트가 닫힌다.
느낀 점
- Function arrow를 사용할 땐, 실제로 함수를 실행하고 있는지, 아니면 함수만 리턴하고 있는지 헷갈릴 수 있다.
- 특히 onClick, onSubmit, onClose 등 콜백을 넘기는 구조에선 이런 실수가 자주 발생한다.
- 작동이 안 될 땐, 이벤트 핸들러에 넘기는 함수 형태를 의심해보자.