[React] 라이프사이클

SOL·2023년 8월 11일
0

React

목록 보기
4/8
post-thumbnail

모든 리액트 컴포넌트에는 라이프사이클이 존재합니다. 컴포넌트의 수명은 페이지에 렌더링되기 전 준비 과정에서 시작하여 페이지에서 사라질 때 끝납니다.

리액트 프로젝트를 진행하다 보면 가끔 컴포넌트를 렌더링할 때 어떤 작업을 미리 처리해야하거나 컴포넌트를 업데이트하기 전후로 어떤 작업을 처리해야할 수도 있습니다. 이때 컴포넌트의 라이프사이클 메서드를 사용합니다.

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



컴포넌트 라이프사이클

컴포넌트의 라이프 사이클은 마운트, 업데이트, 언마운트 총 3가지 카테고리로 나눕니다.

마운트

DOM이 생성되고 웹 브라우저에 나타나는 것을 마운트(mount)라고 합니다. 마운트 할 때 호출하는 메서드들은 다음과 같습니다.

  • constructor: 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드
  • getDerivedStateFromPros: props에 있는 값을 state에 넣을 때 사용하는 메서드
  • render: UI를 렌더링하는 메서드
  • componentDidMount: 컴포넌트가 웹 브라우저에 나타난 후 호출하는 메서드

업데이트

컴포넌트는 총 4가지 경우에 업데이트 됩니다.

첫째. 부모 컴포넌트에서 넘겨주는 props가 바뀔 때,
둘째. 자신이 들고 있는 state가 세터 함수를 통해 바뀔 때,
셋째. 부모 컴포넌트가 리렌더링 될 때,
넷째. this.forceUpdate()와 같은 특정 함수로 강제로 리렌더링 할 때 입니다.

업데이트 시 다음과 같은 메서드들을 호출합니다.

  • getDerivedStateFromProps: 이 메서드는 마운트 과정에서도 호출되며, 업데이트가 시작하기 전에도 호출됩니다. props의 변화에 따라 state값에도 변화를 주고 싶을 때 사용합니다.
  • shouldComponentUpdate: 컴포넌트가 리렌더링 해야 할지 말지를 결정하는 메서드입니다. 이 메서드는 true 혹은 false를 반환해야하며, true를 반환하면 다음 라이프사이클 메서드를 계속 실행하고, false를 반환하면 작업을 중지하고 리렌더링 되지 않습니다.
  • render: 컴포넌트를 리렌더링 합니다.
  • getSnapShotBeforeUpdate: 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출하는 메서드입니다.
  • componentDidUpdate: 컴포넌트의 업데이트 작업이 끝난 후 호출하는 메서드입니다.

언마운트

컴포넌트를 DOM에서 제거하는 것을 언마운트(unmount)라고 합니다.

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


라이프사이클 메서드

라이프사이클 메서드의 종류는 총 아홉 가지입니다.Will 접두사가 붙은 메서드는 어떤 작업을 작동하기 전에 실행되는 메서드이고, Did 접두사가 붙은 메서드는 어떤 작업을 작동한 후에 실행하는 메서드 입니다.

1. render()

라이프사이클 메서드 중 유일한 필수 메서드입니다. 이 메서드 안에서 리액트 요소를 반환합니다. 요소는 div 같은 태그가 될 수도 있고 자식 컴포넌트가 될수도 있습니다. 아무것도 보여주고 싶지 않다면 null이나 false값을 반환해야 합니다.


2. constructor()

컴포넌트의 생성자 메서드로 컴포넌트를 만들 때 처음으로 실행됩니다. 이 메서드에서 초기 state를 정할 수 있습니다.

constructor(props) { ... }

3. getDerivedStateFromProps()

props로 받아온 값을 state에 동기화시키는 용도로 사용하며, 컴포넌트가 마운트 될 때와 업데이트 될 때 호출됩니다.

static getDerivedStateFromProps(nextProps, prevState) {
	if(nextProps.value !== prevState.value){
    	return { value: nextProps.value};
    }
  
  	return null;
}

4. componentDidMount()

컴포넌트를 만들고, 첫 렌더링을 다 마친 후 실행됩니다. 이 메서드 안에서 이벤트 등록, 비동기 작업 등을 처리하면 됩니다.

componentDidMount() { ... }

5. shouldComponentUpdate()

props 또는 state를 변경했을 때, 리렌더링을 시작할지 말지 여부를 지정하는 메서드입니다. 이 메서드에서는 반드시 true/false 값을 반환해야 합니다.

shouldComponentUpdate(nextProps, nextState) { ... }

6. getSnapshotBeforeUpdate()

render()에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출되는 메서드 입니다. 이 메서드에서 반환하는 값은 componentDidUpdate에서 세번째 파라미터인 snapshot 값으로 전달받을 수 있습니다. 주로 업데이트하기 직전의 값을 참고할 일이 있을 때 활용됩니다.

스크롤바 위치 유지에 사용하는 예시입니다.

getSnapshotBeforeUpdate(nextProps, prevState) {
	if(prevState.array !== this.state.array){
    	const { scrollTop, scrollHeight } = this.list
        return { scrollTop, scrollHeight };
    }
}

7. componentDidUpdate()

리렌더링을 완료한 후 호출됩니다. prevProps, prevState를 통해 컴포넌트가 이전에 가졌던 데이터에 접근할 수 있으며 getSnapshotBeforeUpdate에서 반환한 값이 있다면 snapshot을 통해 전달받을 수 있습니다.

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

8. componentWillUnmount()

컴포넌트를 DOM에서 제거할 때 호출됩니다. componentDidMount에서 등록한 이벤트, 타이머, 직접 생선한 DOM이 있다면 여기서 제거 작업을 해야합니다.

componentWillUnmount() { ... }

9. componentDidCatch()

컴포넌트 렌더링 도중에 에러가 발생했을 때 애플리케이션이 멈추지 않고 오류 UI를 보여줄 수 있게 합니다.

componentDidCatch(error, info) {
	this.setState({
    	error: true
    });
  	console.log({error, info});

}

error 파라미터는 어떤 에러가 발생했는지 알려주며, info 파라미터는 어디에 있는 코드에서 오류가 발생했는지에 대한 정보를 줍니다.



useEffect

함수형 컴포넌트에서는 useEffect Hook을 사용하여 렌더링될 때마다 특정 작업을 수행할 수 있습니다. 클래스형 컴포넌트의 componentDidMout와 componentDidUpdate를 합친 형태로 보아도 무방합니다.

마운트 될때

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

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

특정 값이 업데이트될 때

useEffect에서 설정한 함수의 두 번째 파라미터의 배열안에 검사하고 싶은 값을 넣어주면 됩니다. 검사하고 싶은 값은 useState로 관리하고 있는 상태 또는 props로 전달받을 값을 넣어주어도 됩니다.

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

언마운트 되기 전 또는 엡데이트되기 직전

useEffect에서 뒷정리(cleanup) 함수를 return 해주어야 합니다. 언마운트될 때만 뒷정리 함수를 호출하고 싶다면 useEffect 함수의 두 번째 파라미터에 비어있는 배열을 넣으면 됩니다.

useEffect(()=>{
	console.log(name)
  	return () =>{
    	console.log('cleanup');
    }
},[name]);
profile
개발 개념 정리

0개의 댓글

관련 채용 정보