[React] Class Component 와 Function Component

jiseong·2021년 9월 14일
0

T I Learned

목록 보기
69/291
post-thumbnail
post-custom-banner

Component 단위 작성

React의 장점으로 앞서 언급되었던 Virtual DOM으로 인한 DOM 관리의 편리함 뿐만 아니라 Component 단위 작성을 통해 생산성과 유지 보수를 용이하게 할 수 있는 장점도 존재한다.

여기서 Component란 앱을 이루는 최소한의 단위로 UI를 독립적이고 재사용이 가능하게 해주는 목적을 가진 조각이라고 생각하면 쉽다.

리액트에서 이러한 컴포넌트를 작성하는 방법에는 2가지가 있다.
Class ComponentFunction Component이 존재하는데 구성요소 차이를 위주로 알아볼 생각이다.

✔️ Rendering JSX

Class Component

import React, { Component } from "react";

class ClassComponent extends Component {
 render() {
   return <h1>Hello, world</h1>;
 }
}

class component를 정의하기 위해서 extends React.Component를 사용해야 하며 렌더링 할 JSX는 render 메서드 내부에 작성해야 한다.

Function Component

import React from "react";
 
const FunctionalComponent = () => {
 return <h1>Hello, world</h1>;
};

or

import React from "react";

function FunctionalComponent() {
 return <h1>Hello, world</h1>;
}

반면에 Function Component는 렌더링 할 JSX를 반환해주기만 하면 된다.

✔️ Passing props

다음과 같이 'jiseong'이라는 이름의 props를 전달한다고 가정해보자.

<Component name="jiseong" />

Class Component

class ClassComponent extends React.Component {
  render() {
    const { name } = this.props;
    return <h1>Hello, { name }</h1>;
 }
}

Class Component는 props를 참조하기 위해 this를 사용해야 한다.

Function Component

const FunctionalComponent = (props) => {
 return <h1>Hello, {props.name}</h1>;
};

or
비구조할당을 이용한
const FunctionalComponent = ({ name }) => {
 return <h1>Hello, {name}</h1>;
};

함수의 argument로 전달하기 때문에 parameter를 이용하여 props을 참조할 수 있다.

✔️ Handling state

다음과 같이 버튼을 누르면 count가 증가되는 앱이 있다고 가정해보자.

Class Component

class ClassComponent extends React.Component {
 constructor(props) {
   super(props);
   this.state = {
     count: 0
   };
 }

 render() {
   return (
     <div>
       <p>count: {this.state.count} times</p>
       <button onClick={() => this.setState({ count: this.state.count + 1 })}>
         Click
       </button>
     </div>
   );
 }
}

우선적으로, state 변수를 사용하기 위해 생성자 내부에서 state key 와 초기값으로 이루어진 state 객체를 생성한다. (여기서는 count라는 key값을 가진 state를 선언해주었다.)

여기서 생성자 내부에 super(props)를 가장 먼저 호출한 이유는 다음과 같다.

React.Component 서브 클래스에 대한 생성자를 구현할 때 super(props)다른 명령문보다 먼저 호출 해야 한다. 그렇지 않으면 this.props는 생성자에서 정의되지 않아 버그가 발생할 수 있다고 한다.

JSX 내부에서 state key 값에 접근할 때 this.state.count와 같은 방법을 사용하며 버튼을 클릭했을 때 state 값을 변경시켜야하는데 이 때, 직접적으로 변경하지 않고 setState 함수를 이용하여 변경한다.

Function Component

const FunctionalComponent = () => {
 const [count, setCount] = React.useState(0);

 return (
   <div>
     <p>count: {count}</p>
     <button onClick={() => setCount(count + 1)}>Click</button>
   </div>
 );
};

Function Component에서는 state 변수를 사용하기 위해서 useState Hook을 사용해야 한다.

useState의 첫번째 값으로는 현재 상태를 나타내며 두번째 값으로는 이를 업데이트하는 함수를 반환한다. (여기서는 count라는 이름과 setCount라는 이름으로 지었다.)

그 후, 단순하게 count를 이용하여 현재 상태를 가져오고 setCount을 통해 state를 업데이트 할 수 있다.

사실 초기의 Function Component에서는 State 변수를 다룰 수 없었는데 React 16.8 이후 useState가 도입되면서 사용이 가능해진 것이다.

✔️ Lifecycle Methods

Lifecycle은 렌더링 타이밍에서 중요한 역할을 한다.
다양한 Lifecycle methods들이 존재하지만 그 중 componentDidMount 와 componentWillUnmount에 대해서 알아보자.

componentDidMount은 첫 번째 렌더링이 완료된 직후에 호출되는 메서드이며
componentWillUnmount은 컴포넌트가 소멸된 시점에 호출되는 메서드이다.

Class Component

class ClassComponent extends React.Component {
 componentDidMount() {
   console.log("Hello");
 }
  
 componentWillUnmount() {
   console.log("Bye");
 }

 render() {
   return <h1>Hello, World</h1>;
 }
}

Function Component

const FunctionalComponent = () => {
 
 React.useEffect(() => {
  
   console.log("Hello");
  
   return () => {
     console.log("Bye");
   };
 }, []);
 return <h1>Bye, World</h1>;
};

useEffect hook의 두번째 argument로 []을 지정 시 componentDidMount를 완벽하게 대체할 수 있다. 즉, 첫 번째 렌더링이 완료된 직후에만 호출된다.

여기서 두번째 argument는 특정 state 값이 변경 시에 useEffect를 다시 호출하고 싶을 때 사용된다.

Function Component에서 componentWillUnmount를 사용하기 위해서는 useEffect 내부에서 함수를 반환하기만 하면 된다.
주로 clearInterval 함수와 같은 subscriptions을 해제하고 싶을 때 사용한다.

결론

내가 느낀 function component의 장점으로는 'mount와 unmount가 되는 코드를 한 곳에서 작성할 수 있어 유지보수가 쉽고 class component보다 코드를 간결하게 작성할 수 있다.' 라고 생각된다.

그리고 추가적으로 상위 컴포넌트에서 하위 컴포넌트(클래스형 컴포넌트 일 때)에게 props를 전달해주며 하위 컴포넌트에서 해당 props를 setTimeout함수를 이용하여 사용할 일이 있다면 Props는 리액트에서 불변(immutable) 값 이지만 this는 변경 가능한 값(mutable)임을 염두해야 한다고 한다.
참조: https://codesandbox.io/s/pjqnl16lm7


Reference

post-custom-banner

0개의 댓글