문제
아래 코드와 같이 UseEffect를 작성했다. 이 함수는 다음과 같은 기능을 한다.
1) mount되면 thunk를 이용해 데이터를 fetch한 후 스토어에 있는 상태 값을 변경하고,
2) unmount되면 clean up 함수를 통해 상태 값을 비워준다.
문제 해결
1번 동작은 잘 이루어졌지만, 2번 동작이 이루어지지 않았다. 콘솔을 찍어보니 아예 clean up 함수 자체가 호출이 되지 않았다. 문제는 바로 async 키워드를 붙여 useEffect 함수를 async 함수로 만든 것이었다. 아마도 비동기 처리가 필요한 코드를 작성했다가 지운 것 같은데 async 키워드는 까먹고 제거하지 못했다. 다음과 같이 코드를 수정하니 정상적으로 clean up 함수가 작동됐다.
async function
근본적인 원인을 해결하고자 mozila에서 async function의 정의를 찾아보았다.
여기서 눈여겨 본 것은 "Promise를 사용하여 결과를 반환한다"는 것이었다.
"Promise를 사용하여 결과를 반환한다"라는 말이 다소 와닿지 않을 수 있다.
좀 더 자세히 살펴보자. 이해를 돕기 위해 greeting이라는 clean up 함수와 유사한 형태의 async 함수를 작성했다.
과연 로그가 출력이 될까?
출력이 되지 않는다!
이번에는 코드를 약간 수정해서 문자열을 리턴하도록 했다.
Promise 객체가 리턴되는 것을 확인할 수 있다!
"Promise를 사용하여 결과를 반환한다"의 의미가 이제 좀 더 와닿을 것이다.
async 함수를 사용하면 임의의 변수나 함수를 return하도록 코드를 작성하더라도 결국엔 Promise 객체가 return된다는 것을 알 수 있다.
결론
- async 함수는 Promise 객체를 리턴하기 때문에 useEffect에 async 키워드를 붙이면 clean up 함수가 제대로 작동하지 않는다.
- 만약 useEffect에서 비동기 처리와 clean up을 동시에 하고 싶다면
- useEffect에 비동기 함수를 정의하고 호출하거나
- useEffect를 여러번 작성한다 (비동기 처리와 clean up을 분리한다).
참고
'트러블슈팅' 카테고리의 다른 글
[트러블슈팅] MySQL FULLTEXT 특정 문자 검색 안될 때 (0) | 2021.08.06 |
---|---|
[트러블슈팅] Invalid keyPath 에러 (0) | 2021.05.28 |
[트러블슈팅] ER_CON_COUNT_ERROR: Too many connections (1) | 2021.05.06 |
[트러블슈팅] Uncaught ReferenceError: kakao is not defined (5) | 2021.04.29 |
[트러블슈팅] mongoose find not working (0) | 2021.03.10 |