웹/React

[React] 라이프 사이클 메서드(class형, Hooks useEffect())

세고래 2021. 7. 27. 05:12

※배워가고 있는 학생입니다. 틀린 부분이 있다면 댓글로 피드백 부탁드립니다.

1) 컴포넌트의 라이프사이클(수명주기)

모든 리액트 컴포넌트에는 라이프사이클(수명 주기)이 존재한다.

컴포넌트의 수명은 페이지에 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 때 끝난다.

리액트 프로젝트를 진행하다 보면 가끔 컴포넌트를 처음으로 렌더링할 때 어떤 작업을 처리해야 하거나 컴포넌트를 업데이트하기 전후로 어떤 작업을 처리해야 할 수도 있고, 또 불필요한 업데이트를 방지해야 할 수도 있다.

이때 컴포넌트의 라이프사이클 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정할 수 있다.

라이프사이클 메서드는 클래스형 컴포넌트에서만 사용할 수 있으나, 함수형 컴포넌트에서는 사용할 수 없는데, Hooks 기능을 사용하여 비슷한 작업을 처리할 수 있다.

 

라이프사이클은 총 세 가지, 즉 마운트, 업데이트, 언마운트 카테고리로 나눈다.

 

 

마운트(mount)

: DOM이 생성되고 웹 브라우저상에 나타나는 것

 constructor: 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드

 getDerivedStateFromProps: props에 있는 값을 state에 넣을 때 사용하는 메서드

 render: 우리가 준비한 UI를 렌더링하는 메서드

 componentDidMount: 컴포넌트가 웹 브라우저상에 나타난 후 호출하는 메서드

 

업데이트(update)

컴포넌트를 업데이트 하는 경우:

1. props가 바뀔 때

2. state가 바뀔 때

3. 부모 컴포넌트가 리렌더링될 때

4. this.forceUpdate로 강제로 렌더링을 트리거할 때

 

 getDerivedStateFromProps: 마운트 과정에서도 호출되며, 업데이트가 시작하기 전에도 호출됨. props의 변화에 따라 state 값에도 변화를 주고 싶을 때 사용

 shouldComponentUpdate: 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정하는 메서드

 render: 컴포넌트를 리렌더링

 getSnapshotBeforeUpdate: 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출하는 메서드

 componentDidUpdate: 컴포넌트의 업데이트 작업이 끝난 후 호출하는 메서드

 

언마운트(unmount)

:마운트의 반대 과정, 즉 컴포넌트를 DOM에서 제거하는 것

 componentWillUnmount: 컴포넌트가 웹 브라우저상에서 사라지기 전에 호출하는 메서드

2) 라이프사이클 메서드 - class component

클래스 컴포넌트는 항상 props 로 기본 constructor를 호출해야 한다.

  • 마운트: DOM에 렌더링 될 때마다
  • 삭제: DOM이 삭제될 때마다

클래스 컴포넌트에서 특정 메서드를 사용해서 컴포넌트가 (언)마운트 될 때, 일부 코드를 작동시킬 수 있다.

이때 사용되는 특정 메서드를 라이프사이클 메서드(생명주기 메서드)라고 부른다. 

라이프사이클 메서드는 여러 종류가 있지만, 여기에서는 주요 메서드 몇가지만 다뤄보겠다.

(render, conctructor, componentDidMount, componentDidUpdate, componentWillUnmount)

 

**Will 접두사가 붙은 메서드: 어떤 작업을 작동하기 전에 실행되는 메서드

**Did 접두사가 붙은 메서드: 어떤 작업을 작동한 후에 실행되는 메서드

 

💡 render () 

render() { ... }

- 데이터가 변경되어 새 화면을 그려야 할 때 자동으로 호출

- render() 함수가 반환하는 JSX를 화면에 그림

- 라이프사이클 메서드 중 유일한 필수 메서드

- 이 메서드 내에서 this.props와 this.state에 접근 가능하고 리액트 요소를 반환

- 이 메서드 안에서는 이벤트 설정이 아닌 곳에서 setState를 사용하면 안 되며, 브라우저의 DOM에 접근해서도 안됨

(DOM 정보를 가져오거나 state에 변화를 줄 때는 componentDidMount에서 처리해야 함)

 

💡 construtor 

constructor(props) { ... }

- 컴포넌트를 만들 때 처음으로 실행

- 해당 컴포넌트가 "마운트되기 전"에 호출

- 이 메서드에서 초기 state를 정할 수 있음

 

💡 componentDidMount 

componentDidMount() { ... }

- 컴포넌트를 만들고, 첫 렌더링을 다 마친 후 실행

- 컴포넌트가 화면에 모두 표현된 이후 해야 하는 작업들을 여기서 진행

(ex. 다른 자바스크립트 라이브러리 또는 프레임워크의 함수를 호출, 이벤트 등록, setTimeout, setInterval, 네트워크 요청 같은 비동기 작업)

 

💡 componentDidUpdate 

componentDidUpdate(prevProps, prevState, snapshot) { ... }

- 리렌더링을 완료한 후 실행

- 업데이트가 끝난 직후이므로, DOM 관련 처리를 해도 무방

- DOM의 정보를 변경할 때 사용

- 여기서는 prevProps 또는 prevState를 사용하여 컴포넌트가 이전에 가졌던 데이터에 접근할 수 있음

- 부모 컴포넌트로부터 전달된 이전 props 와, 이전 state을 인자로 전달받음

💡 componentWillUnmount 

componentWillUnmount() { ... }

- 컴포넌트를 DOM에서 제거할 때 실행 

- componentDidMount에서 등록한 이벤트, 타이머, 직접 생성한 DOM이 있다면 여기서 제거 작업을 해야 함

3) useEffect - Hooks

앞서 언급했듯, 라이프사이클 메서드는 클래스 컴포넌트에서만 사용할 수 있다.

하지만 함수형 컴포넌트에서도 Hooks 를 이용해 비슷한 기능을 낼 수 있는데, 그것이 바로 useEffect 함수 이다.

 

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

컴포넌트가 mount 됐을 때, unmount 됐을 때, update 됐을 때 특정작업을 수행한다.

 

  • 기본 형태: useEffect(function, deps)

- function: 수행하고자 하는 작업

- deps: 배열 형태이며, 배열 안에는 검사하고자 하는 특정 값 or 빈배열 (업데이트되는 값)

 

1) 마운트 될 때만 실행하고 싶을 때(컴포넌트가 처음 렌더링될 때)

** life cycle중 componentDidmount처럼 실행

useEffect에서 설정한 함수를 컴포넌트가 화면에 맨 처음 렌더링될 때만 실행하고, 업데이트될 때는 실행하지 않으려면 함수의 두 번째 파라미터로 비어 있는 배열을 넣어 주면 된다.

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

2) 마운트, 특정 값이 업데이트될 때 모두 실행하고 싶을 때

**componentDidUpdate, componentDidmount 둘 모두 실행하는 것과 동일

useEffect를 사용할 때, 특정 값이 변경될 때에도 호출하고 싶을 경우도 있을 것이다.

그 경우에는, useEffect의 두 번째 파라미터로 전달되는 배열 안에 검사하고 싶은 값을 넣어 주면 된다.

검사하고 싶은 값, 즉 업데이트되는 그 '특정 값'을 넣으면 된다.

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

배열 안에는 useState를 통해 관리하고 있는 상태를 넣어 주어도 되고, props로 전달받은 값을 넣어 주어도 된다.

지금 이 경우에는, []안에 들어간 특정 값이 업데이트 될 때에도 호출되고, 마운트될 때에도 호출된다.

 

**마운트 될 때는 실행 안 하고, 업데이트 될 때만 실행시키고 싶을 때(일종의 꼼수!)

const mounted=useRef(false);
useEffect(()=>{
	if(!mounted.current){
    mounted.current=true;
    }else{
    //업데이트 될 때 실행할 내용
    }
}, [바뀌는 값]);

mount 될 때 useEffect 부분이 실행되는 것은 막지 못하지만, mount 될 때는 아무 내용도 실행하지 않게 하면 업데이트될 때만 진짜 실행시킬 내용을 실행할 수 있다!

 

3) 컴포넌트가 unmount 되거나 update 되기 직전 (clean up 함수)

**componentWillUnmount처럼 실행

컴포넌트가 언마운트되기 전이나 업데이트되기 직전에 어떠한 작업을 수행하고 싶다면 useEffect에서 뒷정리(cleanup) 함수를 반환해 주어야 한다.

  • 언마운트 될 때만 cleanup 함수 실행하고 싶을 때 - 두번째 파라미터에 빈 배열을 넣는다
  • 특정 값이 업데이트 되기 직전에 cleanup 함수를 실행하고 싶을 때 - deps 배열 안에 검사하고 싶은 값을 넣어준다
useEffect(() => {
    console.log(‘effect‘);
    console.log(name);
    return () => {
      console.log(‘cleanup‘);
      console.log(name);
    };
  });

 

참고: deps에 특정 값 넣기❗

위에서 본 것처럼, deps 에 특정 값을 넣게 되면 컴포넌트가 처음 마운트 될 때, 특정 값이 바뀔 때, 언마운트 될 떄, 특정 값이 바뀌기 직전에 호출된다.

useEffect 안에서 사용하는 상태나 props가 있다면, useEffect 의 deps 에 넣어주어야 하는 것이 원칙이다.

만약 사용하는 값을 넣어주지 않는다면, useEffect 안의 함수가 실행될 때 최신 상태, props 를 가리키지 않는다.

deps 파라미터를 생략한다면, 컴포넌트가 리렌더링 될 때마다 useEffect 함수가 호출된다.

 

 

 

**리액트 컴포넌트는 기본적으로 부모컴포넌트가 리렌더링되면 자식 컴포넌트 또한 리렌더링이 된다. 

바뀐 내용이 없을지라도.

4) 참고자료

- 리액트를 다루는 기술

https://thebook.io/080203/

 

더북(TheBook): 리액트를 다루는 기술 [개정판]

 

thebook.io

- https://velog.io/@delilah/React-5-Component-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%9D%98-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0

 

[React] 5 - Component > 컴포넌트의 생명주기

goalcomponent 생명주기의 모든 것모든 컴포넌트는 여러 종류의 “lifecycle methods”를 가지며, 이 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정할 수 있다.=> when an instance of a component

velog.io

- 웹 게임을 만들며 배우는 리액트 (zero cho)

https://www.inflearn.com/course/web-game-react/dashboard

 

[무료] 웹 게임을 만들며 배우는 React - 인프런 | 강의

웹게임을 통해 리액트를 배워봅니다. Class, Hooks를 모두 익히며, Context API와 React Router, 웹팩, 바벨까지 추가로 배웁니다., 8개의 간단한 웹게임을 만들어보며 배우는 리액트 강좌입니다.React Hooks에

www.inflearn.com

 

728x90

' > React' 카테고리의 다른 글

[ React ] Recoil 사용하기  (0) 2022.07.22
[React] 참고자료 : useEffect 관련  (0) 2021.07.28
[React] 반복되는 컴포넌트 효율적으로 사용 (map() 함수)  (0) 2021.07.24
[React] JSX  (0) 2021.07.11