외부 서버로 fetch한 후 결과를 업데이트하는 컴포넌트가 있는데, 이런 저런 이유로 중간에 컴포넌트를 DOM에서 unmount하는 경우 위와 같은 경고가 발생할 수 있다. 당연히 컴포넌트가 DOM에서 언마운트됐기 때문에 존재하지 않는 컴포넌트에 상태를 업데이트할 순 없을 것이다.
function WarningComponent() {
const [state, setState] = useState()
async function warningFunction() {
const result = await fetch(...)
// WarningComponent unmounted
setState(result) // Warning: Can't perform a React state update...
...
}
}
해결하는 방법은 아래와 같다.
useRef
를 통해 컴포넌트 마운트 상태를 가지는 reference 변수를 생성한다.useEffect
를 통해 컴포넌트 마운트, 언마운트 시 위 변수 값을 변경한다.function NoWarningComponent() {
const [state, setState] = useState()
const isMounted = useRef(false)
useEffect(() => {
isMounted.current = true
return () => isMounted.current = false
}
async function noWarningFunction() {
const result = await fetch(...)
// WarningComponent unmounted
if (isMounted.current) {
setState(result) // Doesn't execute
}
}
}
이를 통해 여러 요청이 이뤄지는 도중 중간에 사용자가 요청을 취소하는 경우, 요청을 수행하는 컴포넌트를 언마운트 하는 방식으로 구현할 수 있다.
(근데 코드가 옆으로 길어지는데.. 좋은 방법이 있으면 알려주세요!)
function NoWarningComponent() {
const [state, setState] = useState()
const isMounted = useRef(false)
useEffect(() => {
isMounted.current = true
return () => isMounted.current = false
}
async function noWarningFunction() {
const result = await fetch(...)
if (isMounted.current) {
const result2 = await fetch(...)
if (isMounted.current) {
const result3 = await fetch(...)
...
}
}
}
}