모든 리액트 컴포넌트에는 라이프사이클
이 존재합니다. 컴포넌트의 수명은 페이지에 렌더링되기 전 준비 과정에서 시작하여 페이지에서 사라질 때 끝납니다.
리액트 프로젝트를 진행하다 보면 가끔 컴포넌트를 렌더링할 때 어떤 작업을 미리 처리해야하거나 컴포넌트를 업데이트하기 전후로 어떤 작업을 처리해야할 수도 있습니다. 이때 컴포넌트의 라이프사이클 메서드를 사용합니다.
라이프사이클 메서드는 클래스형 컴포넌트에만 사용할 수 있습니다. 그러나 함수형 컴포넌트에서도 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
접두사가 붙은 메서드는 어떤 작업을 작동한 후에 실행하는 메서드 입니다.
라이프사이클 메서드 중 유일한 필수 메서드입니다. 이 메서드 안에서 리액트 요소를 반환합니다. 요소는 div 같은 태그가 될 수도 있고 자식 컴포넌트가 될수도 있습니다. 아무것도 보여주고 싶지 않다면 null이나 false값을 반환해야 합니다.
컴포넌트의 생성자 메서드로 컴포넌트를 만들 때 처음으로 실행됩니다. 이 메서드에서 초기 state를 정할 수 있습니다.
constructor(props) { ... }
props로 받아온 값을 state에 동기화시키는 용도로 사용하며, 컴포넌트가 마운트 될 때와 업데이트 될 때 호출됩니다.
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.value !== prevState.value){
return { value: nextProps.value};
}
return null;
}
컴포넌트를 만들고, 첫 렌더링을 다 마친 후 실행됩니다. 이 메서드 안에서 이벤트 등록, 비동기 작업 등을 처리하면 됩니다.
componentDidMount() { ... }
props 또는 state를 변경했을 때, 리렌더링을 시작할지 말지 여부를 지정하는 메서드입니다. 이 메서드에서는 반드시 true/false 값을 반환해야 합니다.
shouldComponentUpdate(nextProps, nextState) { ... }
render()에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출되는 메서드 입니다. 이 메서드에서 반환하는 값은 componentDidUpdate에서 세번째 파라미터인 snapshot 값으로 전달받을 수 있습니다. 주로 업데이트하기 직전의 값을 참고할 일이 있을 때 활용됩니다.
스크롤바 위치 유지에 사용하는 예시입니다.
getSnapshotBeforeUpdate(nextProps, prevState) {
if(prevState.array !== this.state.array){
const { scrollTop, scrollHeight } = this.list
return { scrollTop, scrollHeight };
}
}
리렌더링을 완료한 후 호출됩니다. prevProps, prevState를 통해 컴포넌트가 이전에 가졌던 데이터에 접근할 수 있으며 getSnapshotBeforeUpdate에서 반환한 값이 있다면 snapshot을 통해 전달받을 수 있습니다.
componentDidUpdate(prevProps, prevState, snapshot) { ... }
컴포넌트를 DOM에서 제거할 때 호출됩니다. componentDidMount에서 등록한 이벤트, 타이머, 직접 생선한 DOM이 있다면 여기서 제거 작업을 해야합니다.
componentWillUnmount() { ... }
컴포넌트 렌더링 도중에 에러가 발생했을 때 애플리케이션이 멈추지 않고 오류 UI를 보여줄 수 있게 합니다.
componentDidCatch(error, info) {
this.setState({
error: true
});
console.log({error, info});
}
error 파라미터는 어떤 에러가 발생했는지 알려주며, info 파라미터는 어디에 있는 코드에서 오류가 발생했는지에 대한 정보를 줍니다.
함수형 컴포넌트에서는 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]);