Front-End/React

[React] Hooks

Voyage_dev 2022. 4. 16. 15:05

Hooks

Hooks은 리액트 v16.8에 새로 도입된 기능으로 함수 형태의 컴포넌트에서 사용되는 몇 가지 기술을 Hook이라 부른다

Hooks은 함수형 컴포넌트에서도 상태 관리를 할 수 있는 useState & 렌더링 직후 작업을 설정하는 useEffect등의 기능 등을 제공하여 기존의 함수형 컴포넌트에서 할 수 없었던 다양한 작업을 할 수 있게 해준다. 만일 앱을 react hook을 사용하여 만든다면 class component. render 등을 안 해도 된다는 뜻이다 즉, 모든 것은 하나의 function 함수형 프로그래밍이 가능해진다는 것이다

Why?? 왜 굳이??

굳이 잘 쓰고 있던 클래스형 컴포넌트를 함수형 컴포넌트로 바꾸는 이유는 클래스는 react를 배우는 데에 있어서 큰 진입장벽이었다. 코드의 재사용성과 코드 구성을 어렵게 만들고, this의 사용이나 이벤트 핸들러의 등록 등 기본적인 JS 문법 사항을 알아야 다룰 수 있었다. 또한, 클래스는 잘 축소되지 않고, reloading을 깨지기 쉽고 신뢰하기 어렵게 만든다. 따라서 react의 최신 기술들이 클래스형 컴포넌트에 효과적으로 적용되지 않았다

  • 클래스의 문법이 어렵다
  • 축소가 어렵다
  • reloading의 신뢰성이 떨어진다
  • 최신 기술의 적용이 효과적이지 않다

이러한 클래스의 단점들을 함수형 컴포넌트로 커버할 수 있다. 하지만 클래스 컴포넌트의 장점인 state 사용이나 life cycle을 직접 다루는 등의 기능을 사용하지 못한다. 이를 해결하이 위해 Hook이 등장했다.

React Hooks를 사용 했을 때와 안 했을 때의 차이

Class Component

import React, { Component } from 'react';

class App extends Component {
  state = {
    count: 0,
  };

  countUpdate(n) {
    this.setState({
      count: n,
    });
  }
  render() {
    const { count } = this.state;
    return (
      <div>
        <div>
          <h1>{count}</h1>
          <button
            onClick={() => {
              this.countUpdate(count + 1);
            }}
          >
            증가
          </button>
        </div>
      </div>
    );
  }
}

export default App;

Hooks

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

const App = () => {
  const [count, setCount] = useState(0);

  return (
    <>
      {count}
      <button onClick={() => setCount(count + 1)}>증가</button>
    </>
  );
};

export default App;

useState가 바로 Hook으로 Hook을 호출 해 함수 컴포넌트(function component)안에 state를 추가했다

useState는 현재의 state값과 이 값을 업데이트하는 함수를 쌍으로 제공한다. 이 함수를 핸들러나 다른 곳에서 호출 할 수 있다. useState는 클래스에서 사용하는 this.setState와 유사하지만 이전 state와 새로운 state를 합치지 않는다는 차이점이 존재한다

useState

useState는 컴포넌트에서 state값을 추가할 때 사용된다. 함수형 컴포넌트에서는 클래스형 컴포넌트처럼 state를 사용할 수 없어, Hook을 사용해서 state와 같은 기능을 할 수 있도로 만들어졌다

하나의 useState 함수는 하나의 상태 값만 관리를 할 수 있기 때문에 만약 컴포넌트에서 관리해야 할 상태가 여러 개면 useStte를 여러번 사용해야 한다

import

import React, { useState } from 'react';

useState는 무엇을 반환?

state는 변수, 해당 변수를 갱신할 함수 이렇게 두 가지를 반환한다. 클래스 컴포넌트와 비교하면 this.state.* 와 this.setState와 유사하다

const [value, setValue] = useState(0);

useState()가 호출되면 배열을 반환하는데, 그 배열의 첫 번째 원소는 상태값이고, 두번째 원소는 상태를 업데이트하는 함수이다. 이 함수에 파라미터를 넣어서 호출하게 되면 전달받은 파라미터로 값이 바뀌게 되고 컴포넌트는 정상적으로 리렌더링 된다

만약 아래와 같이 Hook을 호출해 state를 추가하고 count를 0으로 초기화 했다면

const App = () => {
	const [count,setCount] = useState(0)
}

클래스 컴포넌트에서는 아래와 같다

class App extends Component {
  state = {
    count: null,
  };

  setCount() {
    this.setState({
      count: 0,
    });
  }

useEffect

useEffect는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정 할 수 있는 Hook이다. 즉, 화면 렌더링이 될 때마다 state값을 내가 필요한 데이터 모양새로 바꿔 업데이트할 때 사용된다. 클래스형 컴포넌트의 componentDidMount와 componentDidUpdate를 합친 형태로 보아도 무방하다

useEffect((안에) ⇒ {익명함수})로 useState로 선언한 state값을 내가 필요한 모양새로 바꿔 화면 렌더링이 될 때마다 업데이트할 수 있다.

import

import React, { useEffect } from 'react';

선언

useEffect의 매개변수는 익명함수 () ⇒ {}와 빈배열 [] 두가지가 들어간다

  • () ⇒ {} : 첫번째 매개변수로 넣은 익명함수를 넣는다. useState로 선언한 상태값 count의 값을 보여준다
  • [] : 두 번재 매개변수로 배열을 넣는다. 특정 값이나 빈배열이 주로 들어간다
    • 빈 배열을 넣으면 화면에 처음 렌더링 (마운트)될 때 한 번만 실행
    • 배열 안에 값을 넣으면 특정 상태값이 업데이트 될 때만 실행
    • 아예 배열을 생략하면 리렌더링이 할 때마다 반복 실행
useEffect(() => {
    document.title = '업데이트 횟수: ${count}';
}, []);
  • mount : 컴포넌트의 첫 번째 렌더링 결과가 실제 돔에 반영된 상태를 말한다

만일 useEffect에서 설정한 함수의 컴포넌트가 화면에 가장 처음 렌더링 될 때만 실행되고 업데이트 할 경우에는 실행 할 필요가 없는 경우에는 두 번째 파라미터로 비어있는 배열을 넣어주면 된다

function myComponent(){
    const [count, setCount] = useState(0); // count라는 state 추가를 해주자
    
    useEffect(() => { // useEffect로 count가 업데이트될 때 마다 값을 보여주자
        document.title = '업데이트 횟수: ${count}';
    }, []); // 빈배열을 추가해서 불필요한 반복렌더링을 막자
    
    return // 버튼에 onClick이벤트가 발생하면 count를 1씩 더해주자
        <button onClick={() => setCount(count+1)}> 
            increase 
        </button>;
}

 

출처 : 아래의 사이트들을 보면서 큰 공부 하였습니다

https://devbirdfeet.tistory.com/56?category=828965

https://studyingych.tistory.com/59?category=898827

https://velog.io/@velopert/react-hooks