SlowButSteady
새로운 시작
SlowButSteady
전체 방문자
오늘
어제
  • 분류 전체보기
    • 개발
      • 멋쟁이사자처럼 프론트엔드 스쿨 4기
      • Today I Learned
      • Weekly I Learned
      • 간단 TIL
      • Etc
      • 이노베이션 캠프 회고록
    • AUS
    • 주절주절

블로그 메뉴

  • 홈
  • 개발
  • 태그
  • 미디어로그

최근 글

티스토리

hELLO · Designed By 정상우.
SlowButSteady

새로운 시작

[WIL] [React] 클래스형 컴포넌트 & 함수형 컴포넌트 & Hooks
개발/Weekly I Learned

[WIL] [React] 클래스형 컴포넌트 & 함수형 컴포넌트 & Hooks

2022. 8. 28. 23:48
728x90

 

함수형 컴포넌트 선언 방식

import React from 'react';

const App = () => {
  const name = '홍길동';
  return <h1>Hello, {name}</h1>
}

 

클래스형 컴포넌트 선언 방식

import React, { Component } from 'react';

class App extends Component {
  render() {
    const name = '홍길동';
    return <h1>Hello, {name}</h1>
  }
}

클래스형 컴포넌트를 현업에서 자주 사용하지 않지만, 클래스형으로 구성된 프로젝트의 유지보수를 위해서 개념을 숙지할 필요성이 있다.

 

클래스 컴포넌트의 핵심

  • class 키워드가 필수로 들어감
import React, {Component} from 'react'

class App extneds Component {
   render() {
     const name = 'react';
     return <div className="react">{name}</div>
   }
}

export default App;

 

  • Component로 상속을 받아야한다.
import React,{Component} from 'react';

class App extends Component {
   render() {
     const name = "react";
     return <div className="react">{name}</div>
   }
}

export default App;

 

  • render() 메소드가 반드시 있어야한다.
import React, {Component} from 'react';

class App extends Component {
    render() {
       const name = "react";
       return <div className="react">{name}</div>
    }
}


export default App;


일반적 차이

 

클래스형 :

  • state, lifeCycle 관련 기능사용이 가능하다.
  • 메모리 자원을 함수형 컴포넌트보다 조금 더 사용된다.
  • 임의 메서드를 정의할 수 있다.

 

함수형:

  • state, lifeCycle 관련 기능사용이 불가능하다, (대신 Hook을 통해 해결)
  • 메모리 자원을 클래스형 컴포넌트보다 덜 사용한다.
  • 컴포넌트 선언에 좀 더 편하다.

 

State 값 사용시 차이점

State : 컴포넌트 내부에서 바뀔 수 있는 값

 

class ClassComponent extends Component {
  state = {
    number: this.props.initNumber
  }
  
  render() {
     return {
       <div className="container">
          <h2>Class style Component</h2>
          <p>Number : {this.state.number}</p>
       </div>
     }
  }
}

 

클래스형 컴포넌트

  • constructor 안에서 this.state 초기값 설정 가능 
constructor(props) {
   super(props);
   
   this.state  = {
     monsters: [],
     userInput: "",
   };
}

 

  • constructor 없이 바로 state 초기값을 설정할 수 있다.
class Monsters extendes Component {
   state = {
     monsters: [],
     userInput: "",
   }
}

 

  • 클래스형 컴포넌트의 state는 객체 형식
this.state = { monsters: [], userInput: "", };

 

  • this.setState 함수로 state의 값을 변경할 수 있다.
onClick = {() => {
   this.setState({number: number * 1});
}}

 

함수형

  • 함수형 컴포넌트에서는 useState 함수로 state를  사용한다.
  • useState 함수를 호출하면 배열이 반환되는데 첫 번째 원소는 현재 상태를 나타낸다.
  • 두 번째 원소는 상태를 바꿔주는 함수
const [message, setMessage] = useState('');

 

props의 사용 차이

props란?

  • 컴포넌트의 속성을 설정 할 때 사용하는 요소
  • 읽기 전용이다.
  • 컴포넌트 자체 props를 수정해서는 안됨
  • 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야한다.
  • 수정 되는 부분은 react

 

클래스형 컴포넌트의 props

  • this.props로 값을 불러올 수 있다.
class MyComponent extends Component {
   render() {
      const {name, favoriteNumber, children} = this.props;
      return (
         <div>
            가입된 이릉은 {name} 입니다. <br/>
            children 값은 {children}입니다 <br/>
            가장 좋아하는 숫자는 {favoriteNumber} 입니다.
         </div>
      )
   }
}

 

함수형 컴포넌트의 props

  • props를 불러욜 필요 없이 바로 호출할 수 있다.
const MyProps = ({ name, children}) => {

  return (
     <div> 
        안녕하세요, 제 이름은 {name} 입니다.
        children 값은 {children} 입니다.
      </div>
  );
}

 


 

Hook

React에서 Hook이란 함수형 컴포넌트에서 사용되는 state와 관련된 기술들을 모아서 일컫는 말이다.

대표적으로 useState()와 useEffect()가 있다.

Hook은 class를 작성하지 않고도 state와 다른 React의 기능들을 사용할 수 있게 해준다.

 

Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 “연동(hook into)“할 수 있게 해주는 함수입니다. Hook은 class 안에서는 동작하지 않습니다. 대신 class 없이 React를 사용할 수 있게 해주는 것입니다.

 

📌 State Hook

import React, { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

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

위는 버튼을 클릭하면 값이 증가하는 간단한 카운터 예시다. 여기서 useState()가 바로 Hook이다.

이는 현재의 state 값과 이 값을 업데이트하는 함수를 쌍으로 제공한다. useState()의 인자는 초기 state 값이다.

 

⚡️ Effect Hook

종종 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작해야 할 때가 있다. 우리는 이러한 동작을 effects 라고 한다. 이는 다른 컴포넌트에 영향을 줄 수도 있고, 렌더링 과정에서는 구현할 수 없는 작업이다.

 

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // 브라우저 API를 이용해 문서의 타이틀을 업데이트
    document.title = `You clicked ${count} times`;
  });

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

위는 리액트가 DOM을 업데이트한 뒤에 문서의 타이틀을 바꾸는 컴포넌트이다. useEffect()를 사용하면, 리액트는 DOM을 렌더링할 때마다 effects 함수를 실행한다. 그리고, effects는 컴포넌트 안에 선언되어 있으므로 props와 state에 접근할 수 있다.

 

위 예제는 cleanup이 필요없는 작업이다. 그러나 어떤 상태를 subscribe하고자 하는 경우에는 cleanup이 필요하다.

memory leak이 발생하기 때문이다.

 

cleanup이란?
useEffect()에서 parameter로 넣은 함수의 return 함수이다. 컴포넌트의 unmount 이전 / update 직전에 어떠한 작업을 수행하고 싶다면 cleanup 함수를 반환해줘야 한다.

 

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

위는 친구의 접속 상태를 구독하는 effect를 사용하고, 구독을 해지해서 해제하는 예제이다. 이 예시에서 컴포넌트가 unmount될 때 리액트는 ChatAPI에서 구독을 해지한다.

 

🔌 다른 내장 Hook

보편적이지는 않지만, 유용한 내장 Hook이 몇 가지 더 있다. 바로 useContext()와 useReducer()이다.

 

function Example() {
  const locale = useContext(LocaleContext);
  const theme = useContext(ThemeContext);
  // ...
}

useContext()는 컴포넌트를 중첩하지 않고 리액트 context를 구독할 수 있게 해준다.

 

function Todos() {
  const [todos, dispatch] = useReducer(todosReducer);
  // ...

useReducer()는 복잡한 컴포넌트들의 state를 reducer로 관리할 수 있게 해준다.

 

Using the State Hook

state 변수 선언하기

 import React, { useState } from 'react';
 
 function Example() {
    const [count, setCount] = useState(0);

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

Hook을 사용하면 this 없이 state에 직접 접근하여 호출할 수 있다. useState는 state 변수, 해당 변수를 갱신할 수 있는 함수 이 두 가지 쌍을 반환한다. 이것이 바로 const [count, setCount] = useState()라고 쓰는 이유다.

 

Using the Effect Hook

useEffect()를 이용하면 리액트에게 컴포넌트 렌더링 이후 어떤 일을 할지 알려줄 수 있다. 리액트는 넘겨받은 함수를 기억했다가 (이 함수가 effect) DOM 업데이트 이후 불러낸다. effect를 통해 문서 타이틀을 지정하거나, 데이터를 가져오거나 API를 불러낼 수 있다.

 

Mount: DOM 객체가 생성되고 브라우저에 나타나는 것을 의미
Update: 컴포넌트가 업데이트(props 또는 state 변경, 부모 컴포넌트가 리렌더링) 될 때의 과정
Unmount: 컴포넌트가 DOM에서 제거되는 것을 의미

 

리액트의 calss 생명주기 메서드로 설명하자면, useEffect()를 componentDidMount와 componentDidUpdate, componentWillUnmount가 합쳐진 것으로 생각해도 좋다.

 

cleanup을 이용하지 않는 Effects

 function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
}

앞 절에서 언급했던 예제를 자세히 짚고 넘어가겠다. 위 코드에서 useEffect() 파라미터에 함수를 전달하고 있는데 이 함수가 바로 effect이다. 컴포넌트를 렌더링할 때 리액트는 이 effect를 기억하였다가 DOM을 업데이트한 이후 실행한다. 이는 매 렌더링 시 똑같이 적용된다.

 

cleanup을 이용하는 Effects

useEffect(() => {
    function handleStatusChange(status) {
        setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
        ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
});

리액트는 컴포넌트의 마운트가 해지될 때 cleanup을 실행한다. 하지만 effect는 매 렌더링마다 실행된다. 따라서 리액트가 다음 차례의 effect를 실행하기 전에 이전 렌더링에서 파생된 effect를 정리하는 것이다.

앞절에서 컴포넌트의 unmount 이전 / update 직전에 어떠한 작업을 수행하고 싶을 때 반환하는 것이 cleanup 함수라고 했다.

  • unmount 이전: useEffect(func, [])
  • 특정값 update 직전: useEffect(func, [특정값])

그리고 cleanup 함수를 사용하게되면, 작동 순서는 리렌더링 -> 이전 effect cleanup -> effect 로 실행이 된다.

 

 

💡Reference💡

더보기

https://koras02.tistory.com/177

https://velog.io/@1998yuki0331/React-Hook-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC-State-Effect-%EC%9C%84%EC%A3%BC%EB%A1%9C

저작자표시 비영리 변경금지 (새창열림)

'개발 > Weekly I Learned' 카테고리의 다른 글

[WIL] DOM, 서버리스  (0) 2022.08.21
[WIL] JavaScript의 ES란? ES5/ES6 문법 차이  (0) 2022.08.14
    '개발/Weekly I Learned' 카테고리의 다른 글
    • [WIL] DOM, 서버리스
    • [WIL] JavaScript의 ES란? ES5/ES6 문법 차이
    SlowButSteady
    SlowButSteady
    하루하루는 성실하게, 인생 전체는 되는대로

    티스토리툴바