mount,update,unmount 시 작업처리

송은·2023년 6월 12일
0
post-thumbnail

useEffect

useEffect는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook이다.

useEffect는 컴포넌트가 mount 됐을 때, update 됐을 때, unmount 됐을 때 특정 작업을 처리할 수 있다.

*클래스형 컴포넌트에서 사용할 수 있었던 생명주기(라이프사이클) 메서드를 함수형 컴포넌트에서도 사용할 수 있게 된 것이다.


첫번째 파라미터에는 함수, 두번째 파라미터에는 의존값이 들어있는 배열(deps)이 들어간다.

useEffect(() => {
    console.log('컴포넌트가 화면에 나타남');
    return () => {
      console.log('컴포넌트가 화면에서 사라짐');
    };
}, []);

1. mount

컴포넌트 마운트 (처음 나타났을 때)

컴포넌트가 화면에 가장 처음 렌더링 될 때 한 번만 실행하고 싶을 때는 deps 위치에 빈 배열을 넣는다.

useEffect(() => {
    console.log('마운트 될 때 실행)');
}, []);

만약 배열을 생략한다면 리렌더링 될 때마다 실행된다.

useEffect(() => {
    console.log('렌더링 될 때 마다 실행');
});

2. update

컴포넌트 업데이트 (특정 props, state가 바뀔 때)

특정값이 업데이트 될 때 실행하고 싶을 때는 deps 위치의 배열 안에 검사하고 싶은 값을 넣어준다.

업데이트 될 때만 실행하는 것이 아니라 마운트 될 때도 실행된다.

useEffect(() => {
    console.log(user);
    console.log('업데이트 될 때 마다 실행');
}, [user]);

+따라서 업데이트 될 때만 특정 함수를 실행하고 싶다면 아래와 같은 꼼수를 사용하면 좋다.

// mounted의 current 값은 false 로 지정
const mounted = useRef(false);	

useEffect(() => {
	if(!mounted.current){
    	mounted.current = true;
    } else {
    // 원하는 코드 실행
    }
}, [바뀌는 값]);

컴포넌트가 마운트 될 때는 if문에서 아무것도 실행하지 않고 mounted 값만 바꿔주고,

else에서 배열 안에 있는 값이 바뀌면, 원하는 코드를 실행할 수 있다.


3. unmount

컴포넌트 언마운트 (사라질때) / 업데이트 되기 직전

  • cleanup 함수 반환 (return 뒤에 나오는 함수이며 useEffect에 대한 뒷정리 함수라고 한다.)
  • 언마운트 될 때만 cleanup 함수를 실행하고 싶을 때 👉 두 번째 파라미터로 빈 배열을 넣는다.
  • 특정값이 업데이트 되기 직전에 cleanup 함수를 실행하고 싶을 때 👉 deps 배열 안에 검사하고 싶은 값을 넣어준다.
useEffect(() => {
    console.log('effect');  // (2) 값이 업데이트 되면 바뀜.
    console.log(name);
    return () => {
      console.log('cleanup'); // (1) 업데이트 직전에 호출되는 함수 (cleanup)
      console.log(name);
    }
}, [])

deps

  • 빈 배열: 처음 나타날 때에만 useEffect에 등록한 함수가 호출된다. (mount)
  • 의존값 존재: 처음 나타날 때, 지정값이 변경될 때 호출 (mount, update)
  • 아예 없는 경우(파라미터를 생략했을 경우): 컴포넌트가 리렌더링 될 때마다 호출

👉 useEffect 안에서 props로 받아온 값을 참조하거나 useState로 관리하고 있는 값을 참조하고 있는 경우에는 deps에 넣어주어야 한다. deps에 넣지 않으면 useEffect에 등록한 함수가 실행될 때 최신 props, 상태를 가리키지 않게된다.


1. 빈 배열

deps에 빈 배열을 넣었을 때는 처음 나타날 때인 마운트 될 때에만 첫번째 파라미터로 등록한 함수가 호출이 된다.

useEffect(() => {
    console.log('컴포넌트가 화면에 나타남');
}, []);

렌더링 되어있는 컴포넌트 예시

이런식으로 컴포넌트가 3개 존재하는 경우 마운트 되면서 콘솔창에 '컴포넌트가 화면에 나타남' 이 3번 나타난다.

하지만 삭제(update)가 일어날 때는 호출되지 않는다.


2. 의존값 존재

deps에 특정값이 존재할 때에는 처음 나타날 때(mount)와 값이 변경될 때마다(update), 언마운트 될 때, 값이 바뀌기 직전에 모두 useEffect에 등록한 함수가 호출된다.

그리고 해당 특정값이 바뀌기 직전에는 cleanup 함수가 반환된다.

useEffect(() => {
    console.log(user);
}, [user]);

3. 생략한 경우

deps 위치에 파라미터를 생략하여 아예 없는 경우 컴포넌트가 리렌더링 될 때마다 useEffect 의 함수가 호출된다. (=모든 컴포넌트가 리렌더링 된다.)

이는 리액트 컴포넌트에서는 부모 컴포넌트가 리렌더링되면 자식 컴포넌트도 리렌더링 되기 때문이다.

useEffect(() => {
    console.log(user);
});

매번 리렌더링 될 때 마다 업데이트가 되지 않은 것 까지 리렌더링 되다보니, 실제 DOM에 변화가 반영되는 것은 바뀐 내용이 있는 컴포넌트에만 해당하지만 Virtual DOM에서는 모든 것을 다 렌더링 하고 있다.

때문에 항목들의 수가 많아지게 된다면 성능이 느려질 수 있는 가능성이 있다.

따라서 Virtual DOM에 렌더링 되는 것도 최소화 해주는 것이 좋다.

이것을 컴포넌트 리렌더링 성능 최적화 라고 한다.


cleanup

실행 시점: 업데이트 직전, 언마우트 전

useEffect 함수에서 return으로 함수를 반환하면 cleanup 함수가 반환된다.

useEffect 의 뒷정리를 담당하는 함수로, 업데이트 직전에 cleanup 함수가 반환된다.

deps가 비어있는 경우 언마운트 시(컴포넌트가 사라질 때) cleanup 함수가 반환된다.

useEffect(() => {
    console.log('user 값이 설정됨');  // (2) 값이 업데이트 되면 바뀜.
    console.log(user);
    return () => {
      console.log('user 값이 바뀌기 전'); // (1) 업데이트 직전에 호출되는 함수 (cleanup)
      console.log(user);
    }
}, [user])

cleanup 함수 실행 결과


mount vs. unmount

마운트 시 하는 작업

  • props로 받은 값을 컴포넌트의 로컬 상태로 설정 (props → state)
  • 외부 API 요청 (REST API 등)
  • 라이브러리 사용 (D3, Video.js 등)
  • setInterval을 통한 반복작업 혹은 setTimeout을 통한 작업 예약

언마운트 시 하는 작업

  • setInterval, setTimeout을 사용하여 등록한 작업을 clear하기 (clearInterval, clearTimeout)
  • 라이브러리 인스턴스 제거



출처

profile
개발자

0개의 댓글