※배워가고 있는 학생입니다. 틀린 부분이 있다면 댓글로 피드백 부탁드립니다.
1) 컴포넌트의 라이프사이클(수명주기)
모든 리액트 컴포넌트에는 라이프사이클(수명 주기)이 존재한다.
컴포넌트의 수명은 페이지에 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 때 끝난다.
리액트 프로젝트를 진행하다 보면 가끔 컴포넌트를 처음으로 렌더링할 때 어떤 작업을 처리해야 하거나 컴포넌트를 업데이트하기 전후로 어떤 작업을 처리해야 할 수도 있고, 또 불필요한 업데이트를 방지해야 할 수도 있다.
이때 컴포넌트의 라이프사이클 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정할 수 있다.
라이프사이클 메서드는 클래스형 컴포넌트에서만 사용할 수 있으나, 함수형 컴포넌트에서는 사용할 수 없는데, Hooks 기능을 사용하여 비슷한 작업을 처리할 수 있다.
라이프사이클은 총 세 가지, 즉 마운트, 업데이트, 언마운트 카테고리로 나눈다.
마운트(mount)
: DOM이 생성되고 웹 브라우저상에 나타나는 것
• constructor: 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드
• getDerivedStateFromProps: props에 있는 값을 state에 넣을 때 사용하는 메서드
• render: 우리가 준비한 UI를 렌더링하는 메서드
• componentDidMount: 컴포넌트가 웹 브라우저상에 나타난 후 호출하는 메서드
업데이트(update)
컴포넌트를 업데이트 하는 경우:
1. props가 바뀔 때
2. state가 바뀔 때
3. 부모 컴포넌트가 리렌더링될 때
4. this.forceUpdate로 강제로 렌더링을 트리거할 때
• getDerivedStateFromProps: 마운트 과정에서도 호출되며, 업데이트가 시작하기 전에도 호출됨. props의 변화에 따라 state 값에도 변화를 주고 싶을 때 사용
• shouldComponentUpdate: 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정하는 메서드
• render: 컴포넌트를 리렌더링
• getSnapshotBeforeUpdate: 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출하는 메서드
• componentDidUpdate: 컴포넌트의 업데이트 작업이 끝난 후 호출하는 메서드
언마운트(unmount)
:마운트의 반대 과정, 즉 컴포넌트를 DOM에서 제거하는 것
• componentWillUnmount: 컴포넌트가 웹 브라우저상에서 사라지기 전에 호출하는 메서드
2) 라이프사이클 메서드 - class component
클래스 컴포넌트는 항상 props 로 기본 constructor를 호출해야 한다.
- 마운트: DOM에 렌더링 될 때마다
- 삭제: DOM이 삭제될 때마다
클래스 컴포넌트에서 특정 메서드를 사용해서 컴포넌트가 (언)마운트 될 때, 일부 코드를 작동시킬 수 있다.
이때 사용되는 특정 메서드를 라이프사이클 메서드(생명주기 메서드)라고 부른다.
라이프사이클 메서드는 여러 종류가 있지만, 여기에서는 주요 메서드 몇가지만 다뤄보겠다.
(render, conctructor, componentDidMount, componentDidUpdate, componentWillUnmount)
**Will 접두사가 붙은 메서드: 어떤 작업을 작동하기 전에 실행되는 메서드
**Did 접두사가 붙은 메서드: 어떤 작업을 작동한 후에 실행되는 메서드
💡 render ()
render() { ... }
- 데이터가 변경되어 새 화면을 그려야 할 때 자동으로 호출
- render() 함수가 반환하는 JSX를 화면에 그림
- 라이프사이클 메서드 중 유일한 필수 메서드
- 이 메서드 내에서 this.props와 this.state에 접근 가능하고 리액트 요소를 반환
- 이 메서드 안에서는 이벤트 설정이 아닌 곳에서 setState를 사용하면 안 되며, 브라우저의 DOM에 접근해서도 안됨
(DOM 정보를 가져오거나 state에 변화를 줄 때는 componentDidMount에서 처리해야 함)
💡 construtor
constructor(props) { ... }
- 컴포넌트를 만들 때 처음으로 실행
- 해당 컴포넌트가 "마운트되기 전"에 호출
- 이 메서드에서 초기 state를 정할 수 있음
💡 componentDidMount
componentDidMount() { ... }
- 컴포넌트를 만들고, 첫 렌더링을 다 마친 후 실행
- 컴포넌트가 화면에 모두 표현된 이후 해야 하는 작업들을 여기서 진행
(ex. 다른 자바스크립트 라이브러리 또는 프레임워크의 함수를 호출, 이벤트 등록, setTimeout, setInterval, 네트워크 요청 같은 비동기 작업)
💡 componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot) { ... }
- 리렌더링을 완료한 후 실행
- 업데이트가 끝난 직후이므로, DOM 관련 처리를 해도 무방
- DOM의 정보를 변경할 때 사용
- 여기서는 prevProps 또는 prevState를 사용하여 컴포넌트가 이전에 가졌던 데이터에 접근할 수 있음
- 부모 컴포넌트로부터 전달된 이전 props 와, 이전 state을 인자로 전달받음
💡 componentWillUnmount
componentWillUnmount() { ... }
- 컴포넌트를 DOM에서 제거할 때 실행
- componentDidMount에서 등록한 이벤트, 타이머, 직접 생성한 DOM이 있다면 여기서 제거 작업을 해야 함
3) useEffect - Hooks
앞서 언급했듯, 라이프사이클 메서드는 클래스 컴포넌트에서만 사용할 수 있다.
하지만 함수형 컴포넌트에서도 Hooks 를 이용해 비슷한 기능을 낼 수 있는데, 그것이 바로 useEffect 함수 이다.
useEffect는 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook으로,
컴포넌트가 mount 됐을 때, unmount 됐을 때, update 됐을 때 특정작업을 수행한다.
- 기본 형태: useEffect(function, deps)
- function: 수행하고자 하는 작업
- deps: 배열 형태이며, 배열 안에는 검사하고자 하는 특정 값 or 빈배열 (업데이트되는 값)
1) 마운트 될 때만 실행하고 싶을 때(컴포넌트가 처음 렌더링될 때)
** life cycle중 componentDidmount처럼 실행
useEffect에서 설정한 함수를 컴포넌트가 화면에 맨 처음 렌더링될 때만 실행하고, 업데이트될 때는 실행하지 않으려면 함수의 두 번째 파라미터로 비어 있는 배열을 넣어 주면 된다.
useEffect(() => {
console.log('마운트될 때만 실행됩니다.');
}, []);
2) 마운트, 특정 값이 업데이트될 때 모두 실행하고 싶을 때
**componentDidUpdate, componentDidmount 둘 모두 실행하는 것과 동일
useEffect를 사용할 때, 특정 값이 변경될 때에도 호출하고 싶을 경우도 있을 것이다.
그 경우에는, useEffect의 두 번째 파라미터로 전달되는 배열 안에 검사하고 싶은 값을 넣어 주면 된다.
검사하고 싶은 값, 즉 업데이트되는 그 '특정 값'을 넣으면 된다.
useEffect(() => {
console.log(name);
}, [name]);
배열 안에는 useState를 통해 관리하고 있는 상태를 넣어 주어도 되고, props로 전달받은 값을 넣어 주어도 된다.
지금 이 경우에는, []안에 들어간 특정 값이 업데이트 될 때에도 호출되고, 마운트될 때에도 호출된다.
**마운트 될 때는 실행 안 하고, 업데이트 될 때만 실행시키고 싶을 때(일종의 꼼수!)
const mounted=useRef(false);
useEffect(()=>{
if(!mounted.current){
mounted.current=true;
}else{
//업데이트 될 때 실행할 내용
}
}, [바뀌는 값]);
mount 될 때 useEffect 부분이 실행되는 것은 막지 못하지만, mount 될 때는 아무 내용도 실행하지 않게 하면 업데이트될 때만 진짜 실행시킬 내용을 실행할 수 있다!
3) 컴포넌트가 unmount 되거나 update 되기 직전 (clean up 함수)
**componentWillUnmount처럼 실행
컴포넌트가 언마운트되기 전이나 업데이트되기 직전에 어떠한 작업을 수행하고 싶다면 useEffect에서 뒷정리(cleanup) 함수를 반환해 주어야 한다.
- 언마운트 될 때만 cleanup 함수 실행하고 싶을 때 - 두번째 파라미터에 빈 배열을 넣는다
- 특정 값이 업데이트 되기 직전에 cleanup 함수를 실행하고 싶을 때 - deps 배열 안에 검사하고 싶은 값을 넣어준다
useEffect(() => {
console.log(‘effect‘);
console.log(name);
return () => {
console.log(‘cleanup‘);
console.log(name);
};
});
❗참고: deps에 특정 값 넣기❗
위에서 본 것처럼, deps 에 특정 값을 넣게 되면 컴포넌트가 처음 마운트 될 때, 특정 값이 바뀔 때, 언마운트 될 떄, 특정 값이 바뀌기 직전에 호출된다.
useEffect 안에서 사용하는 상태나 props가 있다면, useEffect 의 deps 에 넣어주어야 하는 것이 원칙이다.
만약 사용하는 값을 넣어주지 않는다면, useEffect 안의 함수가 실행될 때 최신 상태, props 를 가리키지 않는다.
deps 파라미터를 생략한다면, 컴포넌트가 리렌더링 될 때마다 useEffect 함수가 호출된다.
**리액트 컴포넌트는 기본적으로 부모컴포넌트가 리렌더링되면 자식 컴포넌트 또한 리렌더링이 된다.
바뀐 내용이 없을지라도.
4) 참고자료
- 리액트를 다루는 기술
더북(TheBook): 리액트를 다루는 기술 [개정판]
thebook.io
[React] 5 - Component > 컴포넌트의 생명주기
goalcomponent 생명주기의 모든 것모든 컴포넌트는 여러 종류의 “lifecycle methods”를 가지며, 이 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정할 수 있다.=> when an instance of a component
velog.io
- 웹 게임을 만들며 배우는 리액트 (zero cho)
https://www.inflearn.com/course/web-game-react/dashboard
[무료] 웹 게임을 만들며 배우는 React - 인프런 | 강의
웹게임을 통해 리액트를 배워봅니다. Class, Hooks를 모두 익히며, Context API와 React Router, 웹팩, 바벨까지 추가로 배웁니다., 8개의 간단한 웹게임을 만들어보며 배우는 리액트 강좌입니다.React Hooks에
www.inflearn.com
'웹 > React' 카테고리의 다른 글
[ React ] Recoil 사용하기 (0) | 2022.07.22 |
---|---|
[React] 참고자료 : useEffect 관련 (0) | 2021.07.28 |
[React] 반복되는 컴포넌트 효율적으로 사용 (map() 함수) (0) | 2021.07.24 |
[React] JSX (0) | 2021.07.11 |