실무에서 리액트로 업무를 하다가 라이프 사이클을 자세히 알지 못해 마주한 이슈가 있었다. 라이프 사이클을 공부하여 문제를 해결한 과정을 기록해둔다.
TODO
유저의 상태가 담긴 데이터를 fetch 해오고 이 데이터를 바탕으로 컴포넌트를 렌더링 해야 함.
이 때 로그아웃 상태면 api 호출 없이 바로 로그아웃 화면 노출, 로그인 시에만 fetch를 해야 함.
의도한 동작
1. 로그인 함수를 불러오고 로그인이 성공하면 전역 context로 로그인 값을 설정,
그리고 이 값을 가져오는 custom Hook을 만듬.(useLogin)
2. fetch가 필요한 컴포넌트에서 useLogin을 이용해 로그인 체크
2-2. 로그인이면 fetch 실행
3. response 값으로 userState를 업데이트 하면 컴포넌트가 유저 상태에 맞게 동적으로 렌더링 될 것으로 예상
👉 2-2 ~ 3은 useEffect 안에서 호출,
문제
1. 사내에서 제공하는 로그인 체크 함수가 느려서 state가 업데이트 되는 시간까지 딜레이가 존재, 그 사이에 디폴트 화면인 로그아웃 상태의 화면이 노출되는 문제 발생.
2. api 요청이 두번씩 들어온다는 문제도 발견.
mount
: 컴포넌트가 최초로 실행될 때render
: 컴포넌트 내의 엘리먼트 요소들을 화면상에 그리는 동작update
: props를 새로 받거나, state가 업데이트 되거나, 부모가 리렌더링 되는 등의 상황에서 컴포넌트를 다시 그리는 동작unMount
: 컴포넌트가 페이지에서 사라질 때클래스 컴포넌트에서는 생명주기와 관련된 메소드들을 제공했었으나,
최근에는 함수형 컴포넌트를 권장하면서 사용되지 않고 있음.
☑️ constructor
컴포넌트 생성자 메서드, 컴포넌트가 생성되면 가장 먼저 실행되는 메서드.
☑️ getDerivedStateFromProps
props로부터 파생된 state를 가져온다. props로 받아온 것을 state에 넣어주고 싶을때 사용.
☑️ componentWillMount
컴포넌트가 렌더링 되기 직전 실행되는 메서드.
☑️ render
컴포넌트를 렌더링하는 메서드.
☑️ componentDidMount
컴포넌트가 마운트 됨, 즉 컴포넌트의 첫번째 렌더링이 마치면 호출되는 메서드.
이 메서드가 호출되는 시점에는 화면에 컴포넌트가 나타난 상태이다.
여기서 주로 DOM을 사용해야 하는 외부 라이브러리, 해당 컴포넌트에서 필요로하는 데이터를 요청하는 등의 동작을 실행.
☑️ getDerivedStateFromProps
컴포넌트의 props나 state가 바뀌었을때도 이 메서드가 호출된다.
☑️ shouldComponentUpdate
컴포넌트가 리렌더링 할지 말지를 결정하는 메서드.
☑️ componentDidUpdate
컴포넌트가 업데이트 되고 난 후에 발생하는 메서드. (최초 렌더링에서는 발생하지 않는다.)
☑️ componentWillUnmount
컴포넌트가 화면에서 사라질 때 발생하는 메서드.
componentDidMount
, componentDidUpdate
, componentWillUnmount
, getDerivedStateFromProps
의 역할을 구현할 수 있다. paint란? 실제 스크린에 Layout을 표시하고 업데이트하는 과정
실행 순서: 컴포넌트 마운트 실행 → 브라우저가 화면에 DOM 그리기(화면 업데이트) → effect 함수 실행
useEffect(() => {
... // 실행할 내용
return () => {
... // clenup
}
},[의존성 배열])
순서: 컴포넌트 마운트 실행 → effect 함수 실행 → 브라우저 화면에 DOM 그리기(화면 업데이트)
useLayoutEffect(() => {
... // 실행할 내용
return () => {
... // clenup
}
},[의존성 배열])