[React] 리액트 Hook에 대한 모든 것

Yeongju Yun·2022년 6월 10일
0

React

목록 보기
5/8

Hook이란?

Hook은 기존 함수형 컴포넌트에서도 클래스형 컴포넌트의 기능을 사용할 수 있게 하는 기능이다. 즉, 함수형 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 연동(hook into) 할 수 있게 해주는 것이 바로 Hook이다.

Hook의 장점

  • 컴포넌트의 함수가 많아질 때 클래스 구성 요소로 리팩토링할 필요가 없다.
  • UI에서 로직을 더 쉽게 분리하여 두 가지 모두 재사용 가능하다.
  • 기존의 코드를 다시 작성할 필요 없이 Hook을 사용할 수 있다.
  • Hook을 사용하면 컴포넌트로부터 상태 관련 로직을 추상화가 가능하다.

Hook 사용하기

React의 Hook을 사용하기 위해서는 사용할 Hook을 import를 해줘야 한다. 만약 State Hook을 사용하기 위해 useState()를 이용하고 싶다면 아래처럼 해주면 된다.

import React, { useState } from 'react';

Hook은 아주 특별한 함수이다. 위에 나온 useState()는 state를 함수 컴포넌트 안에서 사용할 수 있게 한다. 이제 함수형 컴포넌트를 사용하던 중 state를 추가하고 싶다면 클래스 컴포넌트로 바꿀 필요 없이 함수 컴포넌트 안에서 Hook을 이용하여 state를 사용하면 된다.


State Hook이란?

Hook이 나오기 전에는 컴포넌트의 상태 관리를 하려면 클래스 기반 React 컴포넌트를 작성해야 했다. 대표적으로 상태 관리가 필요한 경우인 사용자 입력을 위한 컴포넌트를 작성한다고 생각해보자.

아래 예제 코드는 사용자의 ID와 이메일을 입력받기 위한 전형적인 React 컴포넌트이다. 클래스 컴포넌트의 this.state 필드에 userID와 email 값을 저장해두고 사용자가 이 값을 변경할 때마다 값이 갱신되고 다시 화면에 반영이 된다.

import React, { Component } from 'react';

class UserFormClass extends Component {
    state =  { userID: "", email: "" }
    handleClick = ({ target: { name, value }  }) => {
        this.setState({ [name]: value })
        }
        render() {
            const { userID, email } = this.state
            return (
                    <>
                      <label>
                      userID:
                        <input
                           type="text"
                           name="userID"
                           value={userID}
                           onChange={this.handleClick}
                         />
                      </label>
                      <label>
                      userID:
                        <input
                          type="email"
                          name="email"
                          value={email}
                          onChange={this.handleClick}
                         />
                      </label>
                    </>
            )
        }
}

이렇게 간단한 상태 관리조차도 클래스 기반 컴포넌트로 작성해야 한다는 점에 대해서 불편했었다. 클래스 기반 컴포넌트는 함수 기반 컴포넌트보다 복잡하고 따라서 오류가 발생하기 쉽고 유지 보수가 힘들기 때문이다.

하지만 State Hook의 useState()를 사용하면 함수형 컴포넌트에서 이를 간단히 사용할 수 있다. 아래와 같은 문법을 이용하면 위의 예시에 등장한 userID나 email 같은 state를 함수형 컴포넌트에서 사용 가능하다.

const [<상태 값 저장 변수>, <상태 값 갱신 함수>] = userState(<상태 초깃값>);

대괄호가 의미하는 것은 무엇일까?

위 자바스크립트 문법은 배열 구조 분해라고 하고, useState를 사용하면 변수에 해당하는 첫 번째 값과 그 값을 변경하는 함수에 해당하는 두 번째 값을 반환합니다. 표기는 보통 [count, setCount] 형식으로 사용한다.

이렇게 useState() 함수를 사용하여 클래스 기반 컴포넌트를 함수 기반으로 작성하면 컴포넌트 상태를 관리하기 위한 코드 역시 매우 간단해진다. useState() 함수는 배열을 리턴하는데 첫 번째 원소는 상태 값을 저장할 변수이고 두 번째 원소는 해당 상태 값을 갱신할 때 사용할 수 있는 함수이다. useState() 함수에 인자로 해당 상태의 초깃값을 넘길 수 있다.


Effect Hook이란?

useEffect()는 단어에서 알 수 있듯이 함수형 컴포넌트에서 side effects들을 실행하는 것이다.

React 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작하는 작업을 이전에도 종종 해보셨을 것이다. 우리는 이런 모든 동작을 “side effects”(또는 짧게 “effects”)라고 한다. 쉽게 말해 함수(React의 함수형 컴포넌트) 외부에서 로컬의 상태 값을 변경하는 것을 말한다. 이러한 과정은 다른 컴포넌트에 영향을 줄 수도 있어 렌더링 과정에서는 구현할 수 없는 작업이다.

Effect Hook의 useEffect()는 함수형 컴포넌트 내에서 이런 side effects를 수행할 수 있게 해준다. 간단한 카운터 예제와 함께 살펴보자.

React 클래스의 생명주기 메소드인 componentDidMount() 나 componentDidUpdate()는 로직이 분리되어 있습니다. 따라서 버튼 클릭 때마다 1씩 count를 하는 카운터 컴포넌트에서 매 렌더링 시에도 count를 갱신하고 State가 업데이트될 때에도 count를 갱신하고 싶다면 두 메소드를 동시에 사용해야 한다.

생명주기 메소드를 사용하는 대신 useEffect()를 이용한다면 쉽게 구현할 수 있다.

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

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

    useEffect() => {
     documen.title = 'You checked ${count} times';

     });

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

useEffect()를 사용하는 방법은 위 코드처럼 내가 원하는 effects(여기서는 document.title을 바꾸는 것)를 동작해줄 함수 useEffect()를 작성해주면 된다. 타이틀 바꾸는 것 외에도 필수적인 API를 불러오거나 데이터를 가져올 때도 사용 할 수 있다. useEffect()를 사용하면 모든 렌더링하는 요소마다 원하는 작업을 수행할 수 있어 코드를 중복할 필요가 없다.

"필수적인 API를 불러오거나 데이터를 가져올 때”는 쉽게 말해 프론트엔드에서 백엔드의 데이터를 사용하는 데 필요한 과정을 말한다. 이러한 과정을 원래는 컴포넌트의 생명주기마다 구현해주어야 했는데, Effect Hook이 이를 간단하게 해준 것이다.

Hook의 규칙

자바스크립트의 함수인 Hook을 사용하기 위한 두 가지 큰 규칙에 대해 알아보자.

1. 최상위(at the Top Level)에서만 Hook을 호출해야 한다.

반복문(while), 조건문 (if) 혹은 중첩된 함수 내에 Hook을 호출하면 안된다. Hook은 렌더링 시 항상 동일한 순서로 호출이 되어야 하며 그렇지 않을 경우 버그가 발생한다.

따라서 React가 useState()와 useEffect()가 여러 번 호출되는 중에도 Hook의 상태를 올바르게 유지할 수 있도록 해줘야 한다. Hook은 React 함수의 최상위(at the top level)에서 호출되는 규칙을 따르면 컴포넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장할 수 있다.

2. 오직 React 함수 내에서 Hook을 호출해야 한다.

Hook을 일반적인 자바스크립트 함수에서 호출하면 안 된다. Hook은 아래에 설명된 곳에서만 호출할 수 있다.

  • React 함수 컴포넌트에서 Hook을 호출할 수 있다.
  • 나만의 Hook에서 Hook을 호출할 수 있다.

0개의 댓글