본문 바로가기
카테고리 없음

React 생명주기

by kicksky 2021. 2. 11.

원래 하려던 것: 클래스 컴포넌트에서 쓰이는 생명 주기 메서드를 함수형 컴포넌트에서 적용하려면 어떻게 해야하는지 다시 정확하게 알기

 

먼저 알고 싶은 것: 클래스 컴포넌트에서 쓰이는 생명 주기 메서드

 

따라서,

 

State와 생명주기에서 다시 시작

- render 메서드는 업데이트가 발생할 때마다 호출되지만, 같은 DOM 노드로 <Clock />을 렌더링하는 경우 Clock 클래스의 단일 인스턴스만 사용된다. 따라서 로컬 state와 생명주기 메서드 등의 기능을 사용할 수 있다.

- 어플리케이션에 컴포넌트가 삭제될 때, 해당 컴포넌트가 사용 중이던 리소스를 확보하기

- 타이머가 DOM에 렌더링 될 때(마운팅), DOM에서 삭제될 때 각각 componentDidMount, componentWillUnmout

 

예시로 나온 <Clock />

1. <Clock /> ReactDOM.render()로 전달 → Clock 컴포넌트의 constructor를 호출 현재 시각이 포함된 객체로 this.state를 초기화

2. Clock 컴포넌트의 render( ) 메서드를 호출 화면에 표시되어야 할 내용 확인 Clock의 렌더링 출력값을 일치시키기 위해 DOM을 업데이트

3. Clock 출력값이 DOM에 삽입 // // componentDidMount( ) 생명주기 메서드를 호출 Clock 컴포넌트는 매초 컴포넌트의 tick( ) 메서드를 호출하기 위한 타이머를 설정하도록 브라우저에 요청

4. 매초 브라우저가 tick() 메서드를 호출 Clock 컴포넌트, setState( )현재 시각을 포함하는 객체를 호출하면서 UI 업데이트를 진행 state가 변경된 것을 인지하고 화면에 표시될 내용을 알아내기 위해 render( ) 메서드를 다시 호출 render( ) 메서드 안의 this.state.date가 달라지고 렌더링 출력값은 업데이트된 시각을 포함 DOM을 업데이트

5. Clock 컴포넌트가 DOM에서 삭제되면 componentWillUnmount 호출

 

state에 대해 기억할 것

- 직접 수정 금지. 대신 setState 사용 (직접 수정하면 렌더링이 일어나지 않음)

- state 업데이트는 비동기적일 수도 있음 (성능 때문. 단일 업데이트로 한꺼번에 처리)

- 대신 setState에 객체가 아닌 함수를 인자로 넘겨줄 수도 있음. 

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

- 업데이트는 병합됨. 변수를 독립적으로 업데이트할 수 있음. (그동안 destructuring으로 다른 변수들도 같이 업데이트 했는데 그럴 필요 없는 듯)

- state는 로컬 또는 캡슐화. props로 자식한테 넘겨줄 수는 있음. 

 

컴포넌트 생명주기

마운트 - 업데이트 - 제거

 

projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

마운트

: 인스턴스 생성되어 DOM에 삽입될 때의 순서

🔹 constructor ( )

- 메서드를 바인딩하거나

- state를 초기화

- 마운트 되기 전에 호출

🔹 render( )

🔹 componentDidMount( ) : 마운트 직후, 트리에 삽입된 직후. DOM 노드가 있어야 하는 초기화 작업

- 즉시 setState를 호출하는 경우 ( 내 경우 ) : 추가적인 렌더링이 발생한다. render( )가 두 번 호출되지만 브라우저가 화면 갱신하기 전에 이루어져서 사용자는 중간 과정을 볼 수 없음. 

=> constructor( ) 에서 초기 state 할당할 수 있음

=> Modal이나 툴팁처럼 렌더링 전에 DOM 노드의 크기나 위치를 먼저 측정해야 하는 경우에는 이러한 방식이 필요

업데이트

: props 또는 state가 변경되었을 때 컴포넌트가 다시 렌더링되면 다음의 순서대로 호출

🔹 render( )

- React 엘리먼트

- 배열과 Fragment

- Portal; 별도의 DOM 하위 트리에 자식을 렌더링

- 문자열과 숫자; 텍스트 노드로 렌더링

- Boolean 또는 null; 아무것도 렌더링하지 X

- 순수해야; 호출될 때마다 동일한 결과를 반환해야 하며, 브라우저와 직접 상호작용 X

🔹 componentDidUpdate( prevProps, prevState, snapshot ) : 갱신 직후에 호출.

- DOM 조작이나 props를 비교하여 네트워크 요청을 보내는 작업에 활용.

- 여기에서 조건문으로 감싸지 않은 채로 setState 하면 무한 루프. 

- shouldComponentUpdate()가 false를 반환하면 호출되지 않음.

🔹 shouldComponentUpdate( nextProps, nextState )

- 현재 state 또는 props의 변화가 컴포넌트의 출력 결과에 영향을 미치는지 여부

- 기본값 true; state가 변화할 때마다 다시 렌더링

- props 또는 state가 새로운 값으로 갱신되어서 렌더링이 발생하기 직전에 호출

- 성능 최적화를 위함 (렌더링 방지하려면 PureComponent 사용)

🔹 getSnapshotBeforeUpdate(prevProps, prevState)

마운트 해제

🔹 componentWillUnmount( ): 마운트 해제되어 제거되지 직전에 호출.

- 타이머 제거, 네트워크 요청 취소

오류 처리

🔹 componentDidCatch( )

기타 API

사용자가 컴포넌트 내에서 직접 호출

🔹 setState(updater, [callback]): 컴포넌트 state의 변경 사항을 대기열에 집어넣고, React에게 해당 컴포넌트와 그 자식들이 갱신된 state를 사용하여 다시 렌더링되어야 한다고 알림 

- 즉각적인 명령이 아니라 요청. 항상 즉각적으로 갱신 X

 

댓글