ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [현장에서 바로 써먹는 리액트 with 타입스크립트] (1) 라이프사이클 함수
    공부라도 하자 2023. 9. 28. 00:49

    5장 클래스 컴포넌트

    5.4 라이프사이클 함수

     

    1) constructor 함수

    클래스 컴포넌트는 기본적으로 클래스이기 때문에 클래스의 생성자 함수를 사용할 수 있다. 클래스 컴포넌트에서 State를 사용하지 않아 State의 초깃값을 설정할 필요가 없다면, 생성자 함수도 생략이 가능하다. 생성자 함수를 사용할 때에는 반드시 Super (props) 함수를 호출하여 상속받은 클래스(Component)의 생성자를 호출해야 한다. 생성자 함수는 해당 클래스 컴포넌트가 생성될 때에 한 번만 호출된다.

     

    2) render 함수

    render 함수는 클래스 컴포넌트의 화면 표시 부분(렌더링되는 부분)을 정의하는 데 사용한다. 즉, render 함수의 반환값이 화면에 표시되게 한다. render 함수는 부모 컴포넌트로부터 받는 Props값이 변경되거나 클래스 컴포넌트 안에서 this.setState를 사용하여 State의 값이 변경되어 화면을 갱신할 필요가 있을 때마다 호출된다.

    따라서 render 함수 안에서 this.setState를 사용하여 State 값을 직접 변경할 경우 무한 루프에 빠질 수 있으므로 주의해야 한다. 

     

     3) getDerivedStateFromProps 함수

    getDerivedStatePromProps 함수는 부모 컴포넌트로부터 받은 Props와 State를 동기화할 때에 사용된다. 부모 컴포넌트로부터 받은 Props로 State의 특정값을 설정하거나 State값이 Props에 의존하여 결정될 때에 getDerivedStateFromProps 함수를 사용한다.

    이 함수에서는 Props로 State를 설정하고 싶을 때에 State에 설정하고 싶은 값을 반환하도록 설정하면 된다. 만약 부모 컴포넌트로부터 전달받은 Props에 의해 State값을 변경할 필요가 없는 경우에는 "null"을 반환하면 된다. 

     

    static getDerivedStateFromProps (nextProps, prevState) {
    	if (nextProps.id !== prevState.id) {
    		return { type: "admin"};
    	}
    
    	return null;
    }

    getDerivedStateFromProps 함수는 컴포넌트가 생성될 때에 Props에 의해 State값을 결정해야 하므로 한 번 호출되며, 이후에는 Props와 State를 동기화해야 하므로 Props가 변경될 때마다 호출된다.

     

     

    4) componentDidMount 함수

    클래스 컴포넌트가 처음으로 화면에 표시된 후 componentDidMount 함수가 호출 된다. 즉, render 함수가 처음 한 번 호출된 후 componentDidMount 함수가 호출 되는 것이다. 이 함수는 컴포넌트가 화면에 처음 표시된 후 한 번만 호출되므로 Ajax 를 통한 데이터 습득이나 다른 자바스크립트 라이브러리와 연동을 수행할 때에 주로 사용된다.

    componentDidMount 함수는 부모로부터 받는 Props이 변경되어도, this.setState로 State값이 변경되어도 두 번 다시 호출되지 않는다. 따라서 render 함수와 달리, 이 함수에 this.setState를 직접 호출할 수 있으며, Ajax를 통해 서버로부터 전달받은 데이터를 this.setstate를 사용하여 State에 설정하기에 가장 적합하다.

     

    5) shouldComponentUpdate 함수

    클래스 컴포넌트는 기본적으로 부모 컴포넌트로부터 전달받은 Props가 변경되거나 클래스 컴포넌트 내부에서 this.setState로 State를 변경하면, 화면을 다시 그리기 위해 리렌더링을 하게 된다. 하지만 특정 이유(보통은 컴포넌트 최적화)로 Props 또는 State가 변경되어도 화면을 변경하고 싶지 않은 경우가 발생할 수 있다. 이와 같이 Props 또는 State의 값이 변경 됐지만, 다시 화면을 그리고 싶지 않은 경우에는 shouldComponentUpdate 함수를 사용하여 컴포넌트의 리렌더링을 제어할 수 있다.

    이 함수에서 false를 반환하면, 컴포넌트의 리렌더링을 수행하지 않도록 막을 수 있다. 다음과 같이 특정 값을 비교하여 리렌더링을 제어할 수 있다.

    shouldComponentUpdate(nextProps: Props, nextState: State) {
    	console.log('shouldComponentUpdate'); 
    	return nextProps.id !== this.props.id;
    }

     

    이와 같이 리렌더링을 제어하는 이유는 화면 렌더링을 최적화하기 위해서이다. 브라우저의 렌더링이 웹 성능에 큰 영향이 있다. 화면을 다시 그리는 리렌더링 역시 리액트에서 가장 비용이 많이 드는 부분이다. 데이터를 비교하고 불필요한 리렌더링을 제어한다면, 좀 더 성능 좋은 앱을 제작할 수 있다.

     

     

    6) getSnapshotBeforeUpdate 함수

    Props나 State가 변경되어 화면을 다시 그리기 위해 render 함수가 호출된 후 render 함수의 반환값이 실제로 화면에 반영되기 바로 직전에 getSnapshotBeforeUpdate 함수가 호출된다. 이 함수에서 반환하는 값은 다음에 소개할 componentDidUpdate 의 세 번째 매개 변수(snapshot)로 전달된다.

    이 라이프사이클 함수는 많이 활용되지는 않지만, 화면을 갱신하는 동안 수동으로 스크롤 위치를 고정해야 하는 경우 등에 사용된다.

    getSnapshotBeforeUpdate 함수를 선언한 후 반환값을 반환하지 않는 경우 또는 getSnapshotBeforeUpdate 함수를 선언하고 componentDidUpdate 함수를 선언하지 않는 경우에는 경고가 발생하므로 주의해서 사용해야 한다.

     

    7) componentDidUpdate 함수

     componentDidUpdate 함수는 컴포넌트가 처음 화면에 표시될 때에는 실행되지 않지만, Props 또는 State가 변경되어 화면이 갱신될 때마다 render 함수가 호출된 후 매번 호출되는 함수이다.

    잘 활용되지는 않지만, getSnapshotBeforeUpdate 함수와 함께 사용하여 스크롤을 수동으로 고정시킬 때에 활용되기도 한다.

    render 함수와 마찬가지로 이 함수는 State값이 변경될 때에도 호출되므로 State값을 변경하는 this.setState를 직접 호출한다면, 무한 루프에 빠질 수 있으므로 사용시 주의해야 한다.

     

    8) componentWillUnmount 함수

    componentWillUnmount 함수는 해당 컴포넌트가 화면에서 완전히 사라진 후 호출되는 함수이다. 이 함수는 보통 componentDidMount 함수에서 연동한 자바스크립트 라이브러리를 해제하거나 setTimeout, setInterval 등의 타이머를 clear Timeout, clearInterval을 사용하여 해제할 때에 사용한다.

    componentWillUnmount 함수는 클래스 컴포넌트가 화면에서 완전히 사라진 후 호출되므로 컴포넌트의 State값을 변경하기 위한 this.setState를 호출하면, 갱신하고자 하는 컴포넌트가 사라진 후이기 때문에 경고가 발생할 수 있다.

     

    9) componentDidCatch 함수

    리액트는 자바스크립트이므로 비즈니스 로직에서 에러의 예외 처리로 try-catch문 을 사용할 수 있다. 하지만 render 함수의 JSX 문법을 사용하는 부분에서 에러가 발생하는 경우 try-catch문을 사용하여 예외를 처리할 수 없다. 이와 같이 render 함수의 JSX 부분에서 발생하는 에러를 예외 처리할 수 있게 도와주는 라이프사이클 함수가 componentDidCatch이다.

    render 함수의 JSX 부분에서 에러가 발생하면, componentDidCatch 함수가 실행된다. 이때 다음과 같이 State를 사용하여 에러가 발생했을 때에 자식 컴포넌트를 표시하지 않게 하거나 에러 화면을 표시함으로써 사용자 경험을 개선할 수 있다.

     

     

    리액트 클래스 컴포넌트의 모든 라이프사이클 함수는 render 함수를 제외하고 모두 생략이 가능하며, 필요할 때에 재정의하여 사용할 수 있다.

     

    10) 호출 순서

    •   컴포넌트가 생성될 때: constructor  getDerivedStateFromProps → render → componentDidMount
    •   컴포넌트의 Props가 변경될 때: getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate
    • 컴포넌트의 State가 변경될 때: shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate
    •   컴포넌트의 렌더링 중 에러가 발생할 때 : componentDidCatch
    •   컴포넌트가 화면에서 제거될 : componentWillUnmount
Designed by Tistory.