앞선 포스팅에서는 didMount라는 state값을 선언해서 중복 호출을 막는 방법을 제시했는데 실제 axios를 사용해서 작성하다 보니 unmount가 될 때 axios 호출을 취소하는 방법을 사용하는 것이 더 좋은 방법처럼 보여서 시도해 보았다.
import axios from "axios"
import { useEffect, useState } from "react"
function Dog({dog}) {
return (
<div>
<h2>Dog</h2>
<img src={dog.message} style={{maxWidth: '400px'}}/>
</div>
)
}
export default function DogRandome() {
const [dog, setDog] = useState(null)
useEffect(() => {
console.count('마운트')
const controller = new AbortController()
axios.get('https://dog.ceo/api/breeds/image/random', {signal: controller.signal})
.then(res => {
console.log('axios 요청 완료')
setDog(res.data)
})
.catch(err => console.error(err.message))
return () => {
console.count('마운트 해제 및 axios 요청 취소')
controller.abort()
}
}, [])
return (
<div>
{dog && <Dog dog={dog}/>}
</div>
)
}
axios에 abort를 하는 기능이 존재하였는데 먼저 AbortController 인스턴스를 생성
const controller = new AbortController()
axios 요청시 signal에 controller에 인스턴스의 signal controller.signal
을 전달해주고
axios.get('https://dog.ceo/api/breeds/image/random', {signal: controller.signal})
원하는 시점에 취소해주면 되었다
controller.abort()
첫번째 axios 호출은 react strict mode의 싸이클 mount -> unmount -> remount중에 unmount에 걸려 취소되고 remount 시점에 실행됨으로써 단 한번 실행되는 것을 확인할 수 있었다.
리액트가 18버전 이상의 strict mode에서 mount -> unmount -> remount 싸이클을 실행하는 이유는 보통의 리액트 사용경험상 발생할 수 있는 싸이클이기에 사전에 검증을 하려는 것으로 보인다.
예를 들면 빠르게 Link를 타고 빠져나갔다가 다시 들어온다던지 하는 것이다.
그럴때에 만약에 위와 같이 cleanup function에 관련된 처리가 없을 경우 불필요하게 api호출을 하게 되거나 혹은 eventListner를 등록했을경우 중복으로 리스너가 등록됨으로 인해 어플리케이션이 망가지게 될 것이기 때문으로 보인다!
React 18: useEffect Double Call; Mistake or Awesome? - https://www.youtube.com/watch?v=j8s01ThR7bQ
안녕하세요 질문이 있어요!! react 18 버전에서 strict-mode 를 해제하지 않고 하는법을 보고 댓글을 남겨요. abort 를 이용하는 방식과, state를 생성해서 useEffect를 2번걸어 작업하는 방식으로 적어주셨는데 strict mode는 개발단에서만 적용이 되고 실제 배포되는 운영쪽에서는 사라지는걸로 알고있는데 이렇게 처리를 해야되는 이유라도 있을까요? 만약 처리를 한다고 해도 실제 배포하고 운영쪽에서는 다른 방향으로 작동이 될수도 있을것 같다는 생각이 들어서요 부디 저에게 구원을 내려주세요 ㅠㅠ