Lifecycle
- 컴포넌트는 생성(mounting) -> 업데이트(updating) -> 제거(unmounting)의 생명주기를 갖는다.
- 리액트 클래스 컴포넌트는 라이프 사이클 메서드를 사용하고, 함수형 컴포넌트는 Hook을 사용한다.
Class Lifecycle
mount
1.constructor(생성자)-컴포넌트가 실행될 때 제일 먼저 호출된다.-this.state
를 이용해 state를 초기화한다.
2.render-화면에 그려진다.-props
나 state
변화가 있을 때마다 호출된다.-부모 컴포넌트에 자식 컴포넌트가 있을 경우 부모 컴포넌트 렌더 후 자식 컴포넌트가 렌더된다.
3.componentDidMount-최초 render()
후 한 번만
호출된다.-render()
가 된 상태(화면에 레이아웃이 보여지는 상태)에서 외부에서 데이터를 가져올 때 사용한다.그 데이터를 this.setState
를 사용해 state
에 저장한다.ex) data loading (api 호출)
4.render-state
가 변경된 상태
5.이벤트 발생 시 이벤트 함수 호출 후 render-자식 컴포넌트에 함수를 props
로 전달하면 자식 컴포넌트에서 이벤트가 발생 후 이벤트 함수가 호출되고 부모 컴포넌트 렌더 후 자식 컴포넌트가 렌더된다.
6.componentDidUpdate-state가 변화한 후 호출된다.
unmount
componentWillUnmount-컴포넌트가 제거될 때 호출된다.
Function Lifecycle
모든 컴포넌트에는 세 단계가 존재합니다.1. Mount2. Update3. Unmount
Mount
이 단계는 컴포넌트가 처음으로 페이지에 마운트되는 단계입니다. 이 단계에서 hook의 흐름은 다음과 같습니다.
- Lazy initializers 실행
- useState에 직접적인 값 대신에 넘겨지는 함수를
게으른 초기화(lazy initializaers)
라고 합니다. 게으른 초기화 함수는 오직 첫 마운트 단계에서만 실행되고, 이 후에 다시 리렌더링이 된다면 이 함수의 실행은 무시됩니다.
- 렌더링
- 컴포넌트 함수 자체를 호출하는 과정입니다. e.g. App(props)
- 모든
useState
hook과 다른 값들이 표현되는 때입니다.
- 이름이 렌더링이긴 하지만, 이 시점에서 DOM이 변경되지는 않습니다.
- 리액트의 DOM 업데이트
- DOM을 업데이트하는 것은 브라우저가 스크린을 그리는 것과는 다릅니다.
- Layout Effects 실행
- 다음 글에서 layout effect에 대해 다룰 것입니다.
- 브라우저의 스크린 그리기
- Effects 실행
Update
이 단계는 컴포넌트가 업데이트되는 단계입니다. 이 업데이트는 다음과 같은 이유들로 발생합니다:
- 부모 컴포넌트의 재렌더링
- 컴포넌트 State 변경
- Context 변경
이 단계에서 hook의 흐름은 다음과 같습니다.
- 렌더링
- 리액트의 DOM 업데이트
- Layout Effects Cleanup 실행
useLayoutEffect
도 useEffect
처럼 클린업 단계가 존재합니다.
- Layout Effects 실행
- 브라우저의 스크린 그리기
- Effects Cleanup 실행
- Effects 실행
보시다시피, 마운트 단계에서 과정과 유사하지만, Layout Effects와 Effects Cleanup
이 실행된다는 것이 차이점입니다.
Unmount
이 단계는 컴포넌트가 페이지로부터 언마운트되는 단계입니다. 이 단계에서 hook의 흐름은 다음과 같습니다.
- Layout Effects Cleanup 실행
- Effects 실행
이 단계에서는 Cleanup만이 실행됩니다.
React Hook
- 함수형 컴포넌트에서도 클래스형 컴포넌트의 기능을 사용할 수 있게 하는 기능이다.
- 훅을 통해 함수형 컴포넌트에서도 컴포넌트 상탯값을 관리할 수 있고, 컴포넌트의 생명 주기 함수를 이용할 수 있다.
장점
- 재사용 가능한 로직을 쉽게 만든다. 훅이 단순한 함수이므로 함수 안에서 다른 함수를 호출하는 것으로 새로운 훅을 만들 수 있기 때문이다. 리액트 내장 훅과 다른 사람들이 만든 여러 커스텀 훅을 조립해서 쉽게 새로운 훅을 만들 수 있다.
- 같은 로직을 한곳으로 모을 수 있어 가독성이 좋다.
- 함수형 컴포넌트들은 기본적으로 리렌더링이 될때, 함수 안에 작성된 모든 코드가 다시 실행됨
- 클래스형 컴포넌트들은 method의 개념이므로, 리렌더링이 되더라도 render() 를 제외한 나머지 method 및 state는 그대로 보존이 되어 있음.
이는 함수형 컴포넌트들이 기존에 가지고 있던 상태(state)를 전혀 관리(기억)할 수 없게 만듦
- 그래서 함수형 컴포넌트를 Stateless Component 라고 했던 것.
- 단순하게 React에서의 state 만을 의미하는 것이 아닌, 함수내에 써져 있는 모든 코드 및 변수를 기억할 수 없다는 의미
⇒ 함수형 컴포넌트가 리렌더링될때 무조건 새롭게 선언 & 초기화 & 메모리에 할당이 됨
하지만 Hook의 등장으로, 브라우저에 메모리를 할당 함으로써, 함수형 컴포넌트가 상태(state)를 가질 수 있게 한 것.
⇒ 쉽게 말해서 함수 내에 써져 있는 코드 및 변수를 기억할 수 있게 됐다 라는 의미
공식홈페이지에 따르면 Hook을 만든 이유는 다음과 같다.
1) 컴포넌트 사이에서 상태 로직 재사용의 어려움 -> render props, HOC 등
2) 복잡한 (클래스형) 컴포넌트들은 이해하기 어려움 -> 각종 생명주기 함수들
3) 클래스자체 개념을 이해하기 어려움 -> this 등
규칙
- 최상위에서만 Hook을 호출
React 함수(컴포넌트)의 최상위에서만 Hook을 호출 할 것.
반복문, 조건문, 중첩된 함수등에서 호출 X
- React 함수에서만 Hook을 호출
Custom Hook에서는 호출 가능
일반적인 Javascript 함수에서는 호출 X
- Hook을 만들때 앞에 use 붙히기
그래야만 한눈에 보아도 Hook 규칙이 적용되는지를 파악할 수 있기 때문 (공홈)
- React는 Hook 호출되는 순서에 의존
한 컴포넌트에서 여러개의 hook이 사용되는 경우
hook은 위에서부터 아래로 순서에 맞게 동작한다.
Hook 종류
기본 Hooks
- useState (동적 상태 관리)
- useEffect (side effect 수행 -mount/unmount/update)
- useContext (컴포넌트를 중첩하지 않고도 전역 값 쉽게 관리)
추가 Hooks
- useReducer (복잡한 컴포넌트들의 state를 관리 -분리)
- useCallback (특정 함수 재사용)
- useMemo (연산한 값 재사용)
- useRef (DOM선택, 컴포넌트 안에서 조회/수정할 수 있는 변수 관리)
- useImperativeHandle
- useLayoutEffect
- useDebugValue
https://ko.reactjs.org/docs/hooks-intro.html
참고링크