Web/Front-End

리액트 Class vs Function style

ansui 2023. 8. 11. 20:05

#0 오리엔테이션

< Class vs Function style >

- Class

: 리액트의 기능 전부 사용 가능

: class 문법을 알아야 하고 장황하다.

: render() 사용

//클래스 방식
class ClassComp extends React.Component {
  render() {
    return (
      <div className="container">
        <h2>class style component</h2>
      </div>
    );
  }
}

 

- Function style

: 기능 부족

: 함수의 문법만 알면 된다.

: state, life cycle API(컴포넌트의 생성, 변경, 소멸 이벤트) 사용 불가능

: 자기 자신이 render()

→ 최신 리액트는 hook 기능 사용 가능!

//함수 방식
function FuncComp(props) {
  return (
    <div className="container">
      <h2>function style component</h2>
    </div>
  );
}

*모두 배워야 한다!!!

 


#1 클래스에서 state 사용법

- 컴포넌트를 사용하는 쪽: 컴포넌트가 제공하는 props를 통해 컴포넌트를 이용할 수 있다.

- 컴포넌트를 만드는 쪽: state를 통해 내부의 작업을 할 수 있다.

*props는 클래스, 함수 모두에서 사용 가능

*state는 클래스에서만 사용 가능

 

 

< 클래스에서 state를 사용하여 Number 출력 >

import React from 'react';

function App() {
  return (
    <div className="container">
      <h1>Hello World</h1>
      <ClassComp initNumber={2}></ClassComp>
      <FuncComp initNumber={2}></FuncComp>
    </div>
  );
}

//클래스 방식
class ClassComp extends React.Component {
  //state를 통해 number=2 넣기
  state = {
    number: this.props.initNumber,
  };
  
  render() {
    return (
      <div className="container">
        <h2>class style component</h2>
        <p>Number: {this.props.initNumber}</p> {/* props 사용 */}
        <p>Number: {this.state.number}</p> {/* state 사용 */}
        
        {/* 버튼을 클릭할 때마다 state값이 바뀌고 render()가 호출되면서 바뀐 결과가 반영 
        function에서는 원래 불가능 -> hook으로 가능! */}
        <input
          type="button" value="random" onClick={
          function () {
            this.setState({ number: Math.random() });
          }.bind(this)}
        ></input>
      </div>
    );
  }
}

//함수 방식
function FuncComp(props) {
  return (
    <div className="container">
      <h2>function style component</h2>
      <p>Number: {props.initNumber}</p> {/* props 사용 */}
    </div>
  );
}

 

 

< 출력 결과 >

초기 화면 & 랜덤 버튼 눌렀을 때

 


#2 함수에서 state 사용법 - hook

< Hook의 개요 >

Hook은 React 버전 16.8부터 React 요소로 새로 추가되었습니다.
Hook을 이용하여 기존 Class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 React의 기능을 사용할 수 있습니다.
import React, { useState } from 'react';

function Example() {
  // "count"라는 새로운 상태 값을 정의합니다.
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

 

*리액트 공식 메뉴얼: https://ko.legacy.reactjs.org/docs/hooks-intro.html 

 

Hook의 개요 – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

 

 

< 함수에서 useState를 사용하여 Number 출력 >

import React, {useState} from 'react';

function App() {
  return (
    <div className="container">
      <h1>Hello World</h1>
      <ClassComp initNumber={2}></ClassComp>
      <FuncComp initNumber={2}></FuncComp>
    </div>
  );
}

//클래스 방식
class ClassComp extends React.Component {
  //state를 통해 number=2 넣기
  state = {
    number: this.props.initNumber,
  };
  
  render() {
    return (
      <div className="container">
        <h2>class style component</h2>
        <p>Number: {this.props.initNumber}</p> {/* props 사용 */}
        <p>Number: {this.state.number}</p> {/* state 사용 */} 
        
        {/* 버튼을 클릭할 때마다 state값이 바뀌고 render()가 호출되면서 바뀐 결과가 반영
        function에서는 원래 불가능 -> hook으로 가능! */}
        <input
          type="button" value="random" onClick={
          function () {
            this.setState({ number: Math.random() });
          }.bind(this)}
        ></input>
      </div>
    );
  }
}

//함수 방식
function FuncComp(props) {
  var numberState = useState(props.initNumber); //초기값으로 number=2 넣기
  var number = numberState[0]; //상태값
  var setNumber = numberState[1]; //상태값을 바꾸는 함수
  console.log(numberState); //배열 2개 출력
  
  return (
    <div className="container">
      <h2>function style component</h2>
      <p>Number: {number}</p>
      <input
          type="button" value="random" onClick={
          function () {
            setNumber(Math.random());
            }
          }></input>
    </div>
  );
}

 

 

< 출력 결과 >

초기 화면 & 랜덤 버튼 눌렀을 때

 

 

< 클래스와 함수에서 Date 출력 >

import React, { useState } from "react";

export default function App() {
  return (
    <div className="container">
      <h1>Hello World</h1>
      <ClassComp initNumber={2}></ClassComp>
      <FuncComp initNumber={2}></FuncComp>
    </div>
  );
}

//클래스 방식
class ClassComp extends React.Component {
  //state를 통해 number=2 넣기
  state = {
    number: this.props.initNumber,
    date: new Date().toString(),
  };
  
  render() {
    return (
      <div className="container">
        <h2>class style component</h2>
        <p>Number: {this.props.initNumber}</p> {/* props 사용 */}
        <p>Number: {this.state.number}</p> {/* state 사용 */}
        <p>Date: {this.state.date}</p> {/* state 사용 */}
        
        {/*버튼을 누르면 랜덤 숫자 생성*/}
        <input
          type="button"
          value="random"
          onClick={function () {
            this.setState({ number: Math.random() });
          }.bind(this)}
        ></input>
        
        {/*버튼을 누르면 현재 날짜 저장*/}
        <input
          type="button"
          value="date"
          onClick={function () {
            this.setState({ date: new Date().toString() });
          }.bind(this)}
        ></input>
      </div>
    );
  }
}

//함수 방식
function FuncComp(props) {
  var numberState = useState(props.initNumber); //초기값으로 number=2 넣기
  var number = numberState[0]; //상태값
  var setNumber = numberState[1]; //상태값을 바꾸는 함수

  var dateState = useState(new Date().toString()); //초기값으로 현재 날짜 넣기
  var date = dateState[0]; //상태값
  var setDate = dateState[1]; //상태값을 바꾸는 함수

  return (
    <div className="container">
      <h2>function style component</h2>
      <p>Number: {number}</p>
      <p>Date: {date}</p>

      {/*버튼을 누르면 랜덤 숫자 생성*/}
      <input
        type="button"
        value="random"
        onClick={function () {
          setNumber(Math.random());
        }}
      ></input>

      {/*버튼을 누르면 현재 날짜 저장*/}
      <input
        type="button"
        value="date"
        onClick={function () {
          setDate(new Date().toString());
        }}
      ></input>
    </div>
  );
}

 

 

< 출력 결과 >

 


#3 클래스에서 라이프 사이클 구현하기

< 함수 방식이 클래스 방식에 버금가는 가능성을 갖게 된 두가지 측면 >

1) State 사용 가능

2) Life Cycle 사용 가능

 

React Life Cycle

*componentWillMount() - 컴포넌트가 생성되기 전에 해야할 일이 있을 때 이 메소드 구현

var classStyle = "color:red";
class ClassComp extends React.Component {

  state = {
    number: this.props.initNumber,
    date: new Date().toString(),
  };
  
  componentWillMount() {
    console.log("%cclass => componentWillMount", classStyle);
  }
  componentDidMount() {
    console.log("%cclass => componentDidMount", classStyle);
  }
  
  render() {
    console.log("%cclass => render", classStyle);
    return (...)
  }
}

 

 

< console 출력 결과 >

class => componentWillMount
class => render
class => componentDidMount

 

 

*클래스에서는 적당한 타이밍에 원하는 코드를 실행할 수 있다.


#4 함수에서 라이프 사이클 구현하기

1) useEffect: side effect

useEffect(function () {
  console.log("%cclass => render", funcStyle);
  document.title = number + ":" + date;
});

: 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 실행할 수 있도록 하는 hook

→ 웹페이지가 처음으로 render()될 때 실행되고, render()가 실행될 때마다 실행된다.

(= componentDidMount & componentDidUpdate)

 

: 여러개 설치 가능

 

 

2) clean up

componentWillMount, componentDidMount - 컴포넌트가 처음으로 돔에 나타나는 순간에 해야하는 초기작업

componentWillUnmount - 컴포넌트가 소멸될 때 해야하는 작업

→ 등장할 때와 퇴장할 때의 작업이 구분된다!

 

useEffect가 실행될 때 초기화 한 후 다시 한번 실행될 때는 이전의 실행을 정리하고 이때 return 함수를 호출하다. 

useEffect(function () {
  console.log("%cclass => useEffect", funcStyle);
  document.title = number + ":" + date;

  return function () {
    console.log("%cclass => useEffectReturn", funcStyle);
  };
});

 

 

3) skipping effect

Optimizing Performance by Skipping Effects

: effect가 호출되는 것을 성능을 위해 생략

 

예) title = number

useEffect(function () {
  console.log("%cclass => useEffect", funcStyle);
  document.title = number;

  return function () {
    console.log("%cclass => useEffectReturn", funcStyle);
  };
});

*number가 변화하지 않으면 굳이 이 작업을 할 필요가 없다.

→ number의 값이 변화할 때만 호출하도록 코드를 변경!

useEffect(function () {
  console.log("%cclass => useEffect", funcStyle);
  document.title = number;

  return function () {
    console.log("%cclass => useEffectReturn", funcStyle);
  }
}, [number]);

→ random 버튼을 눌렀을 때만 호출되고 date 버튼을 눌렀을 때는 호출되지 않는다.

 


Egoing Lee님의 인프런 "생활코딩 - React class vs. function style coding" 강의를 참고하여 정리하였습니다.

'Web > Front-End' 카테고리의 다른 글

React.js 기초 #3 JSX  (0) 2023.11.04
React.js 기초 #2 Create React App  (0) 2023.11.04
React.js 기초 #1 React를 사용하는 이유  (0) 2023.11.04
OpenWeather API로 날씨 웹사이트 만들기  (0) 2023.08.30
OAuth 2.0 기본 개념  (0) 2023.08.07