State Lifecycle
생명주기
- React에서 모든 컴포넌트는 아래의 세가지 단계를 거침
┌ 초기화 단계
├ 업데이트 단계
└ 소멸 단계
- 위의 각 단계에서 몇개의 메서드들이 정해진 순서대로 작동하고 각 단계 속에서 호출되는 메서드들을 바로 생명주기 메서드 라고 부름
- 리액트는 웹에서 UI 데이터가 변경되면 자동으로 컴포넌트가 업데이트되고 동적으로 화면을 그려줌
- 제대로 된 기능을 수행하려면 이런 자동으로 업데이트 되는 과정에 끼어들어 API를 호출하기도 하고 데이터를 가공해줘야 할 때도 있음
- 따라서, 생명주기의 각 단계별로 필요한 순간에 필요한 작업들을 끼워넣을 수 있는 메서드들이 존재함

└ 위의 사진은 리액트의 라이프 사이클을 나타낸 화면
생명주기의 각 메서드들의 역할
- 초기화 단계
┌ 초기화 단계에서는 최초에 컴포넌트 객체가 생성 될 때 한번 수행되는 과정
└ 초기화 단계에서 실행되는 함수
① constructor()
┌ 메서드를 바인딩하거나 state(상태)를 초기화 하는 작업이 없다면 constructor(생성자)가 없어도 됨
├ react 컴포넌트의 constructor(생성자)는 해당 컴포넌트가 마운트 되기 전에 호출됨
├ 생성자를 구현하면 this.props가 생성자 내에서 정의 되도록 super(props)를 호출해줘야 함
└ state의 값을 변경하고자 한다면, constructor() 외부에서 this.setState()를 통해 수정해야 함
② render()
┌ class 컴포넌트에서 반드시 구현되야 하는 유일한 메서드
├ 이 메서드를 호출하면 this.props와 this.state값을 활용해 값을 반환해야 함
├ render() 함수는 컴포넌트의 state를 변경하지 않고 호출 될 때마다 동일한 결과를 반환해
브라우저와 직접적인 상호작용을 하지 않음
③ componentDidMount()
┌ 컴포넌트가 마운트 된 직후에 호출됨
├ DOM 노드가 있어야 하는 초기화 작업이 이루어지면 좋음
└ 외부에서 데이터를 불러와야 한다면 네트워크 요청을 보내기 좋은 위치
- 업데이트 단계
┌ 업데이트 단계는 컴포넌트가 마운트 된 이후 컴포넌트의 props(속성값)과 state(상태값)이 변경되면
업데이트 단계가 실행됨
└ 업데이트 단계에서 실행되는 함수
① componentDidUpdate()
└ render가 일어난 직후에 호출되며 최초 렌더링에서는 호출 되지 않음
- 소멸 단계
┌ 소멸단계에서는 컴포넌트가 소멸 할 때의 과정
└ 소멸단계에서의 함수
① componentDidWillUnMount()
┌ 컴포넌트가 마운트 해제되 제거되기 직전에 호출
├ 타이머 제거, 네트워크 요청 취소, componentDidMount()에서 생성된 작업 등을 정리할 때 사용
└ 실행 직후 컴포넌트는 렌더링 되지 않으므로 setState() 호출을 하면 안됨
클래스형 컴포넌트와 함수 컴포넌트의 생명주기 차이점
- React에서 클래스형과 함수로 컴포넌트를 생성할 수 있는데, 요새는 클래스형보다 함수 컴포넌트가 많이 사용됨
- 함수 컴포넌트와 별개로 요즘은 화살표 함수 const를 자주 사용함
클래스형 컴포넌트 | 함수 컴포넌트 | |
특징 | ① render() 메서드와 Component | ① 간편한 컴포넌트 선언 및 프로그래밍 가능 ② React Hook 사용 |
단점 | ① state, props 사용에 불편함이 있음 ② 메모리 사용량이 늘어남 |
① state와 생명주기 메서드를 별도로 구분해야함 ex) useState, useEffect 사용 |
클래스형 컴포넌트 생명주기 예시
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, createRef } from "react"; | |
import Router from "next/router"; | |
interface IState { | |
count: number; | |
} | |
export default class ClassCounterPage extends Component { | |
inputRef = createRef<HTMLInputElement>(); | |
// createRef는 react에서 제공하는 기능 | |
state = { | |
count: 0, | |
}; | |
componentDidMount() { | |
console.log("마운트 됨"); | |
this.inputRef.current?.focus(); // input에 커서가 깜빡 거리게 됨 | |
} | |
componentDidUpdate() { | |
console.log("수정되고 다시 그려짐"); | |
} | |
componentWillUnmount() { | |
console.log("여기서 나갈래요"); | |
} | |
onClickCounter = () => { | |
console.log(this.state.count); | |
this.setState((prev: IState) => ({ | |
count: prev.count + 1, | |
})); | |
console.log("카운터를 클릭하셨습니다."); | |
}; | |
onClickMove = () => { | |
Router.push("/"); | |
}; | |
render() { | |
return ( | |
<div> | |
<input type="text" ref={this.inputRef} /> | |
<div>현재카운트: {this.state.count}</div> | |
<button onClick={this.onClickCounter}>카운트 올리기</button> | |
<button onClick={this.onClickMove}>나가기</button> | |
</div> | |
); | |
} | |
} |
함수형 컴포넌트 생명주기 예시
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useRef, useState } from "react"; | |
import { useRouter } from "next/router"; | |
export default function FunctionLifeCycleRefPage() { | |
const router = useRouter(); | |
const inputRef = useRef<HTMLInputElement>(null); | |
const [count, setCount] = useState(0); | |
// componentDidMount와 동일 | |
useEffect(() => { | |
console.log("마운트 됨"); | |
inputRef.current?.focus(); // input에 커서가 깜빡거림 | |
// componentWillUnmount 동일 | |
return () => { | |
console.log("여기서 나갈래요"); | |
}; | |
}, []); // []는 의존성 배열 | |
// componentDidUpdate와 비슷(동일하지 않음. 1%가 다름) | |
useEffect(() => { | |
console.log("수정되고 다시 그려짐"); | |
// 카운트 올리기 버튼을 누르면 reFresh됨 | |
// 렌더 될때도 실행됨 | |
}); | |
const onClickCounter = () => { | |
console.log(count); | |
setCount((prev) => prev + 1); | |
console.log("카운터를 클릭하셨습니다."); | |
}; | |
const onClickMove = () => { | |
router.push("/"); | |
}; | |
console.log("이건 언제 실행되냐.."); | |
return ( | |
<div> | |
<input type="text" ref={inputRef} /> | |
<div>현재카운트: {count}</div> | |
<button onClick={onClickCounter}>카운트 올리기</button> | |
<button onClick={onClickMove}>나가기</button> | |
</div> | |
); | |
} |
useEffect
useEffect
- React Hook에서 라이프사이클 구현에 사용되는 함수
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
//코드 | |
}) |
└ 2번째 파라미터를 주지 않으면 모든 컴포넌트가 리렌더링될 때마다 실행됨 (메모리 과다 사용)
componentDidMount() :
렌더링이 완료된 후 호출되는 메서드 대신 쓸 때
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
// 코드 | |
}, []) //빈배열을 줌으로써 마운트 이후 1회만 실행 |
└ 마운트 이후 1회만 실행됨
componentDidUpdate() & getDerivedStateFromProps() :
컴포넌트 업데이트 작업 완료 후 실행되는 메서드 대신 쓸 때
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
// 코드 | |
}, [props명, state명, ...]) |
└ 2번째 파라미터 배열에 명시한 변수가 변경될 때만 실행
componentWillUnmount() :
컴포넌트가 DOM에서 제거될 때 호출되는 메서드 대신 쓸 때
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
// 코드 | |
return () => { | |
// unmount나 unsubscribe 코드 | |
} | |
}, [props명, state명, ...]) |
└ effect(함수 혹은 변수 등)가 필요없어지면 return 함수를 실행하여 메모리 반환
'React > 2022-上' 카테고리의 다른 글
State Lifting (0) | 2022.04.04 |
---|---|
State Prev (0) | 2022.04.04 |
Class / Functional Component (클래스형 컴포넌트, 함수형 컴포넌트) (0) | 2022.03.28 |
React state, props (0) | 2022.03.27 |
JavaScript와 TypeScript (0) | 2022.03.27 |