본문 바로가기

DEVELOP

[React.js] 메모리 누수에 관하여

728x90

리액트를 사용하다 보면 간혹 콘솔창에 빨갛게 memory leak.... 어쩌고 경고문이 나올때가 있다.

몇번 마주칠때마다 구글링을 해봐도 와닿지 않았는데 결론은 

데이터를 담아 사용 useState()를 다시 비워주지 않아서 발생한다.

 

React는 DOM를 직접 건드리지 않고 선언적(원하는 바를 간접적으로 명시?)으로 돌아가는데 (이부분은 좀더 공부가 필요)

그럴때 사용하는 것이  react의 useState이다. 

(참고: javascript나 jquery에서는 DOM에 접근하기 위해 아이디 값이나 클래스값을 직접 호출하는데 React에서 요소를 변경하려면 react의 useRef()를 사용한다. 이부분 공부 필요...)

즉, 이해한 바로는 메모리 누수는 말그대로 메모리가 계속 새고 있다는 것인데, 한번 사용한 그릇을 비우지않고 다른 페이지로 넘어간다면 그 그릇에 내용이 계속 남아 새고있다는 뜻이다. 

그래서 useEffect를 사용하여 사용한 그릇을 비워주어야 한다.

 

예시) 데이터 담고 사용 후 리셋 (.tsx)

Test.tsx

import { useState, useEffect } from "react";
import { focusHandler, resetHandler } from "function/ModalScroll";

function Test() {
const [data, setData] = useState<any[]>([]);
// data
const imgArr = [login, main, sub1, sub2, sub3, sub4];
useEffect(() => {
    let isMount = true;
    if (isMount) {
        setData(imgArr);
    }
    return () => {
        isMount = false;
        setData([]);
    };
	}, []);
}

export default Test;
isMount란 boolean 변수를 사용하여 해당 변수가 true일때 배열 형식의 데이터를 담고 
Test 컴포넌트 return 안에선 data란 변수로 데이터를 사용하다가,
페이지를 떠날땐, useEffect의 return 안에서 setData([]);로 해당 그릇을 비워준다.


그렇다면 함수를 사용할땐 어떻게 사용하고 비우는지 알아보자.

예시) 함수 활용후 리셋 (.tsx)

Test.tsx

import { useState, useEffect } from "react";
import { focusHandler, resetHandler } from "function/ModalScroll";

function Test() {
    const [func, setFunc] = useState<any>({ on: null, off: null });
    useEffect(() => {
        let isMount = true;
        if (isMount) {
           setFunc({ on: focusHandler, off: resetHandler });
        }
        return () => {
            isMount = false;
            setFunc({});
        };
	}, []);
}

default export Test;

사용했던 함수 

function/ModalSrcoll.ts

export const focusHandler = (e: any) => { document.body.style.overflow = "hidden"; }
export const resetHandler = (e: any) => { document.body.style.overflow = "initial"; }