-
클래스형 컴포넌트와 함수형 컴포넌트React 2021. 8. 5. 20:38
📋 클래스형 컴포넌트와 함수형 컴포넌트
리액트 컴포넌트는 클래스형 컴포넌트 또는 함수형 컴포넌트로 작성될 수 있다.
클래스형 컴포넌트는 상태값을 가질 수 있고, 리액트 컴포넌트의 생명 주기 함수를 작성할 수 있다. 그러나 함수형 컴포넌트는 이 모든 일을 할 수 없다. 이 둘의 차이점은 상태값과 LifeCycle를 가질 수 있느냐 없느냐이다.리액트 버전 16.8부터 훅(Hook)이 등장하면서 함수형 컴포넌트에서도 상태값과 생명 주기 함수 코드를 작성 할 수 있게 되었다.
📕 함수형 컴포넌트
☑️ JSX를 return문을 사용해서 반환
☑️ state를 사용할 수 없다
☑️ 생명 주기 함수를 작성할 수 없다
import React from 'react'; function Hello({ color, name, isSpecial }) { return ( <div style={{ color }}> {isSpecial && <b>*</b>} 안녕하세요 {name} </div> ); } export default Hello;
📕 클래스형 컴포넌트
☑️ class 키워드로 시작
☑️ Component로 상속 받음
☑️ render() 함수를 사용해서 JSX를 반환
☑️ props를 조회할 때 this 키워드 사용
import React, { Component } from 'react'; class Hello extends Component { render() { const { color, name, isSpecial } = this.props; return ( <div style={{ color }}> {isSpecial && <b>*</b>} 안녕하세요 {name} </div> ); } } export default Hello;
☑️ defaultProps 설정 시 클래스 내부에 static 키워드와 함께 선언
import React, { Component } from 'react'; class Hello extends Component { // defaultProps 설정 방법 1 static defaultProps = { name: '이름없음' }; render() { // ... ); } // defaultProps 설정 방법 2 Hello.defaultProps = { name: '이름없음' }; } export default Hello;
🔖 커스텀 메서드 만들기
☑️ 클래스의 생성자 메서드 constructor 에서 bind 작업
import React, { Component } from 'react'; class Counter extends Component { constructor(props) { super(props); this.handleIncrease = this.handleIncrease.bind(this); this.handleDecrease = this.handleDecrease.bind(this); } handleIncrease() { console.log('increase'); console.log(this); } handleDecrease() { console.log('decrease'); } render() { return ( <div> <h1>0</h1> <button onClick={this.handleIncrease}>+1</button> <button onClick={this.handleDecrease}>-1</button> </div> ); } } export default Counter;
🔖 상태 선언하기
☑️ 클래스형 컴포넌트에서 state로 상태를 관리
☑️ state 를 선언 할 때에는 constructor 내부에서 this.state 설정
☑️ 클래스형 컴포넌트의 state 는 무조건 객체형태여야 한다
☑️ render 메서드에서 state 를 조회하려면 this.state 를 조회하면 된다.
import React, { Component } from 'react'; class Counter extends Component { state = { counter: 0 }; handleIncrease = () => { this.setState({ counter: this.state.counter + 1 }); }; handleDecrease = () => { this.setState({ counter: this.state.counter - 1 }); }; render() { return ( <div> <h1>{this.state.counter}</h1> <button onClick={this.handleIncrease}>+1</button> <button onClick={this.handleDecrease}>-1</button> </div> ); } } export default Counter;
🔖 상태 업데이트 하기
☑️ 상태를 업데이트해야 할 때에는 this.setState 함수를 사용
🔖 LifeCycle Method (생명 주기 메서드)
☑️ 생명 주기 함수를 작성할 수 있다
출처: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
LifeCycle Method는 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드들이다. 추가적으로 컴포넌트에서 에러가 났을 때 호출되는 메서드도 있다.
생명주기 메서드는 클래스형 컴포넌트에서만 사용 할 수 있다.
컴포넌트 라이프 사이클은 크게 마운트 - 업데이트 - 언마운트로 단계로 나뉜다.
실제 프로덕션에서 아래 여섯가지 위주로 life cycle을 관리한다.
🔘 constructor
🔘 render
🔘 componentDidMount
🔘 shouldComponentUpdate
🔘 componentDidUpdate
🔘 componentWillUnmount🔍 마운트 단계 (초기화 단계)
마운트 단계(초기화 단계)는 최초에 컴포넌트 객체가 생성될 때 한 번 수행된다. 먼저 마운트될 때 발생하는 생명주기들을 알아보자.
1️⃣ constructor
2️⃣ getDerivedStateFromProps
3️⃣ render
4️⃣ componentDidMountconstructor
constructor(props) { super(props); }
constructor는 컴포넌트의 생성자 메서드, 컴포넌트가 만들어지면 가장 먼저 실행되는 메서드이다. 컴포넌트가 브라우저에 나타나기전 즉, render()전에 호출이되는 라이프 사이클 함수이다.
getDerivedStateFromProps
static getDerivedStateFromProps(nextProps, prevState) { if (nextProps.color !== prevState.color) { return { color: nextProps.color }; } return null; }
getDerivedStateFromProps 메소드는 속성값을 이용해서 새로운 상태값을 만들때 즉, props로 받아온 것을 state에 넣어주고 싶을 때 사용한다.
이 메소드는 render 메서드가 호출되기 직전에 호출되는 라이프 사이클 함수이다.
다른 생명주기 메서드와는 달리 앞에 static을 필요로 하고, 정적 메서드이기 때문에 함수 내부에서 this 객체에 접근할 수 없다.
render
컴포넌트를 렌더링하는 메서드로 컴포넌트를 정의할 때 반드시 작성해야 한다.
render 메서드에서는 부수 효과를 발생시키면 안 된다. 서버와 통신하기, 브라우저의 쿠키에 저장하기 등은 부수 효과이므로 render 메서드 내부에서는 피해야 한다. 만약 부수 효과가 필요하다면 다른 생명 주기 메서드에서 하면 된다.
componentDidMount
componentDidMount() { // 외부 api호출, DOM 에 관련된 작업 등 }
componentDidMount 메서드는 render 메서드의 첫 번째 반환값이 실제 돔에 반영된 직 후 호출된다.
따라서 render 메서드에서 반환한 리액트 요소가 돔에 반영되어야 알 수 있는 값을 얻을 수 있기 때문에 해당 컴포넌트에서 필요로 하는 데이터를 요청하기 위해 axios, fetch등을 이용해 외부 api를 호출하는 작업을 진행한다.
🔍 업데이트 단계
업데이트 단계는 초기화 단계와 소멸 단계 사이에서 반복해서 수행된다. 컴포넌트의 속성값 또는 상태값이 변경되면 업데이트 단계가 수행된다. 이 단계에서 실행되는 생명 주기 메서드의 호출 순서는 아래와 같다.
1️⃣ getDerivedStateFromProps
2️⃣ shouldComponentUpdate
3️⃣ render
4️⃣ getSnapshotBeforeUpdate
5️⃣ componentDidUpdategetDerivedStateFromProps
컴포넌트의 props나 state가 바뀌었을때도 이 메서드가 호출된다.
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState) { // return false 하면 업데이트를 안함 return true; // 기본값으로는 true를 반환 }
shouldComponentUpdate는 컴포넌트 최적화를 할 때 많이 사용 된다. 이 메서드는 컴포넌트가 리렌더링 할지 말지를 결정하는 메서드이다.
render
컴포넌트를 렌더링하는 메서드이다.
getSnapshotBeforeUpdate
getSnapshotBeforeUpdate(prevProps, prevState) { if (prevProps.color !== this.props.color) { return this.myRef.style.color; } return null; }
getSnapshotBeforeUpdate 메서드는 렌더링 결과가 실제 돔에 반영되기 직전에 호출된다.
따라서 getSnapshotBeforeUpdate 메서드가 호출되는 시점에 이전 돔 요소의 상태값을 가져오기 좋다.componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot) { console.log("업데이트 되기 직전 색상: ", snapshot); } }
componentDidUpdate 메서드는 업데이트 단계에서 마지막으로 호출되는 생명 주기 메서드다. 이 메서드는 가상 돔이 실제 돔에 반영된 후 호출된다. 따라서 componentDidUpdate 는 새로 반영된 돔의 상태값을 가장 빠르게 가져올 수 있는 메서드이다.
3번째 파라미터로 getSnapshotBeforeUpdate에서 반환한 값을 조회 할 수 있다.
🔍 언마운트 단계 (소멸 단계)
마지막으로 언마운트 단계에서는 다음 생명 주기 메서드가 호출된다.
1️⃣ componentWillUnmount
componentWillUnmount
componentWillUnmount() { // 이벤트 및 연동된 외부 라이브러리 제거 }
componentWillUnmount 메서드는 컴포넌트가 화면에서 사라지기 직전에 호출된다.
주로 사전에 해당 컴포넌트에 등록했었던 이벤트 및 연관 외부 라이브러리 호출등을 제거할 수 있다.
> 참고 : https://taling-react-course.com/intro/lifecycle-api.html
> 참고 : https://react.vlpt.us/basic/25-lifecycle.html
'React' 카테고리의 다른 글
useState Hook (0) 2021.08.02 Link와 NavLink (0) 2021.07.29 Redux Thunk (0) 2021.06.14 react-redux 패키지와 Hooks 사용하기 (0) 2021.06.13 Redux로 상태 관리하기 (0) 2021.06.12