✨ 크게 세가지 유형으로 나눌 수 있다.
생성될 때 (마운트) : DOM이 생성되고 웹 브라우저 상에 나타날 경우
(컴포넌트가 보이는 순간, 페이지에 장착이되는 순간이라고도 표현한다.)
업데이트할 때 (업데이트)
: 업데이트는 다음과 같은 4가지 상황에서 발생
제거할 때 (언마운트) : DOM에서 제거될 경우
📌 Check!
리액트 컴포넌트는 기본적으로 부모컴포넌트가 리렌더링되면 바뀐 내용이 없더라도 자식 컴포넌트 또한 리렌더링된다.
실제 DOM 에 변화가 반영되는 것은 바뀐 내용이 있는 컴포넌트에만 해당하지만, Virtual DOM 에는 모든걸 다 렌더링하고 있다.
▲ 리액트의 라이프 사이클은 9개가 존재한다.
라이프사이클 메서드(Lifecycle Method)는 '생명주기 메서드'로, 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 (+컴포넌트에서 에러가 났을 때) 호출되는 메서드들이다.
생명주기 메서드는 클래스형 컴포넌트에서만 사용 할 수 있다. useEffect
랑 비슷하다고 생각하면 되지만 작동방식도 많이 다르고 커버하지 않는 기능들도 있다.
(자주 사용하지 않는 메서드도 있으니 어떤 것들이 있는지만 간단하게 살펴보고 위에서 세가지 유형으로 나뉜 도표를 위주로, useEffect
와 같이 공부하자 ✍️ )
1. constructor 🌟
컴포넌트를 만들 때 처음으로 실행된다. 초기 state를 정할 수 있다.
클래스형에서는 constructor, 함수형에서는 useState
를 사용해서 초기 상태를 설정한다.
2. getDerivedStateFromProps
props로 받아 온 값을 state에 동기화시키는 용도로 사용한다.
3. shouldComponentUpdate
props나 state를 변경했을 때, 리렌더링을 할지 말지 결정한다. true나 false를 반환해야 한다.
✍️ 보통은 클래스형 → PureComponent
, 함수형 → props는 React.memo
, state는 useMemo
를 활용하면 렌더링 성능을 개선할 수 있다고 한다.
4. render 🌟
컴포넌트를 렌더링할 때 필요하다. 필수 메서드이며, 함수형 컴포넌트에서는 render를 안쓰고도 컴포넌트를 렌더링할 수 있다.
5. getSnapshotBeforeUpdate
render에서 만들어진 결과가 브라우저에 실제로 반영되기 직전에 호출된다.
6. componentDidMount 🌟
useEffect
를 활용하여 구현한다.// Class
class Example extends React.Component {
componentDidMount() {
...
}
}
// Hooks
const Example = () => {
useEffect(() => {
...
}, []); // useEffect의 [] 의존성 배열을 비워야지만 똑같은 메소드를 구현할 수 있다.
}
7. ComponentDidUpdate 🌟
리렌더링을 완료한 후 실행한다. 업데이트가 끝난 직후이므로, DOM관련 처리를 해도 무방하다.
// Class
class Example extends React.Component {
componentDidUpdate(prevProps, prevState) {
...
}
}
// Hooks
const Example = () => {
useEffect(() => {
...
});
}
8. componentWillUnmount 🌟
useEffect CleanUp
함수를 통해 구현한다.// Class
class Example extends React.Component {
coomponentWillUnmount() {
...
}
}
// Hooks
const Example = () => {
useEffect(() => {
return () => {
...
}
}, []);
}
9. componentDidCatch
컴포넌트 렌더링 도중 에러가 발생하면, 애플리케이션이 멈추지 않고 오류 UI를 보여줄 수 있게 해준다.
useEffect 훅은 컴포넌트가 마운트 됐을 때(처음 나타났을 때), 언마운트 됐을 때(사라질 때), 업데이트 될 때(특정 porps가 바뀔 때) 특정 작업을 처리한다.
useEffect
훅은 여러가지 기능을 할 수 있는데, 그 중 라이프사이클을 대체할 수도 있다. (❗️ 대체를 할 수 있지만 100% 일치하는 개념은 아니다. )
마운트 시에 주로 하는 작업들
언마운트 시에 주로 하는 작업들
useEffect
useEffect
는 함수이다.- 첫번째 파라미터로 함수가 들어간다.
- 두번째 파라미터로
deps(React.DependencyList)
를 추가할 수 있는데, 이것은 의존값이 들어있는 배열이다.
[]
을 설정하지 않으면(생략하면) → 리렌더링 될 때마다 호출된다. 즉, 항상 렌더가 된 직후에는 이 함수를 실행하라는 의미이다. React.useEffect(() => {
console.log('componentDidMount');
});
[]
빈 배열을 설정하면 → 최초에만 실행이된다. 즉 컴포넌트가 처음 나타날 때만 useEffect
에 등록한 함수가 호출된다. (componentDidMount만 해당된다고 볼 수 있을 것 같다.) React.useEffect(() => {
console.log('componentDidMount');
}, []);
deps
안에 특정 값이 있다면 언마운트시에도 호출이되고, 값이 바뀌기 직전에도 호출이 된다. React.useEffect(() => {
console.log('componentDidMount');
}, [count]);
useEffect
안에서 사용하는 상태나 props가 있다면, useEffect
의 deps
에 넣어주는 것이 규칙이다.useEffect
안에서 사용하는 상태나 props를 deps
에 넣지 않으면 useEffect에 등록한 함수가 실행될 때 최신 props 상태를 가르키지 않게 된다.useEffect
에서는 함수를 반환 할 수 있는데 이를 cleanup 함수라고 부른다. 즉, useEffect
안에서 return 할 때 실행된다.deps
가 비어있는 경우에는 컴포넌트가 사라질 때 cleanup 함수가 호출된다.useEffect
코드가 실행이 되기 전에 먼저 실행이 되는 특성을 활용한다.useEffect
에 타이머 함수를 둔다면 재렌더링이 될 때마다 예상치 않게 ( ,[]
를 안썼을경우) 여러개의 타이머가 생길 수 있다. 이때 기존 타이머를 제거해달라는 코드를 cleanup 코드 안에 넣을 수 있다.useEffect
는 무조건 최초에 한 번은 실행이 된다.useEffect
가 실행된다.useEffect
는 render와 deps와 밀접한 관련이 있다. React.useEffect(() => {
console.log('componentDidMount & componentDidpdate by count');
}, [count]);
✍️ 라이프사이클 메서드와 useEffect를 코드를 통해서 비교&이해하기
export default function DepsTest() {
const [count, setCount] = useState(0);
React.useEffect(() => {
...
}); // 1) 두번째 파라미터로 의존값이 들어있는 배열인 deps를 추가할 수 있다.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={click}>Click !!</button>
</div>
);
function click() {
setCount(count + 1);
}
}
1-1)
[]
을 생략하고 호출해본다.
React.useEffect(() => {
console.log('componentDidMount & componentDidUpdate', count);
});
1-2)
[]
을 빈 배열로 호출해본다.
React.useEffect(() => {
console.log('componentDidMount', count); // 1)
},[]);.
deps
는 useEffect
의 첫번째 파라미터 함수가 실행될 타이밍을 조절한다고 한다.dpes
는 보통 비워두지 않으며, 만약 deps에 영향을 주는 1)count와 같은 것을 사용함에도 비워둔다면 Lint가 밑줄을 그어서 알려준다.🧐1-3)
[]
에 특정값을 준다.
React.useEffect(() => {
console.log('componentDidMount, componentDidUpdate by count', count);
}, [count]);
deps
에 count가 있으므로 count가 변했을 때만 컴포넌트 렌더가 업데이트된 것에 의해 useEffect
가 실행되므로 componentDidMount by count 의 의미를 갖는다.useEffect
는 render + deps와 밀접한 관계가 있다. 따라서 lifecycle과 완전히 같다고 볼 수 없다고 한다.2) deps는 여러개 사용이 가능하다.
React.useEffect(() => {
console.log('먼저 실행');
}, []);
React.useEffect(() => {
console.log('다음 실행');
}, []);
useEffect
는 여러개를 사용할 수 있고 순차적으로 실행된다.deps
상황에 맞을 때만 해당 useEffect
첫번째 파라미터 함수가 실행된다.3) cleanup
ex. 1)
export default function DepsTest() {
const [count, setCount] = useState(0);
React.useEffect(() => {
console.log('componentDidMount'); // 1)
return () => { // 2)
// cleanup
// componentWillUnmount
console.log('cleanup');
};
}, []); // 빈 배열일 경우 최초만 실행
retrun( // 렌더
...
)
}
useEffect
는 return을 할 수 있는데 이 공간을 cleanup
이라고 부른다.deps
의해서 useEffect가 실행될 때 직전에 2)가 먼저 실행, 그 다음 1)을 실행한다.deps
를 빈 배열로 둔다면 최초에만 실행이 된다. 이때 cleanup이 일어나려면 결국 DepsTest
자체가 사라질 때 말고는 없다.cleanup
위치는 정확하게 componentWillUnmount의 역할을 하게된다.ex. 2)
React.useEffect(() => {
// 1) 렌더가 된 직후
console.log('componentDidMount, componentDidUpdate by count');
return () => { // 2)
console.log('cleanup'); // cleanup
};
},[count]);
deps
의해서 useEffect가 실행될 때 직전에 2)가 먼저 실행, 그 다음 1)을 실행한다.useEffect
가 실행된다. 카운트 click 버튼을 누르면 새로운 카운트 값이 아니고 이전 카운트 값으로 ▼console.log('cleanup by count', count)
가 실행되고 나서 렌더 후 ▼console.log('componentDidMount, componentDidUpdate by count', count)
가 실행된다.useEffect
함수가 실행될 때 그 전에 미리 이전 deps
값으로 리턴 함수를 실행하고 그 다음으로 넘어간다. 😀 📌 Check!
1.useEffect(()=>{ ... })
: 재렌더링마다 코드실행
2.useEffect(()=>{ ... }, [])
: mount시 1회 코드실행
3.useEffect(()=>{ return(()=>{...}) }, [])
: unmount시 1회 코드실행
4.return()=>{...}
: useEffect 실행 전에 먼저 실행할 코드가 필요하다면 언제나 return문
5.useEffect(()=>{ ... }, [state명])
: mount시 + 특정 state 변경시에만 실행
❓Lifecycle을 왜 알아야할까?
: 내가 lifecycle을 알고 있으면 컴포넌트의 Lifecycle(mount, update, unmount)에 간섭을 할 수가 있게된다. 😀
✍️ 최근에는 Hooks를 활용해서 함수형 컴포넌트를 사용하는 방향으로 나아가고 있다고 한다. 기존 라이프사이클의 개념에 대해 이해하고, Hooks를 활용해서 라이프 사이클을 구현하는 것에 대해서 익숙해져야겠다.
어려울 땐 ▼ 사이트 참고하기 !
📌 useEffect 완벽 가이드
(Dan Abramov가 작성한 ‘A Complete Guide to useEffect’의 번역문)
reference)
react-lifecycle_method
vlpt-useEffect
vlpt-lifecycle_method
Lifecycle이해
fastcampus-react
dreamcoding
codingapple