개발자취/JAVASCRIPT

처음 써 본 리액트 훅(Hook) 후기..

까연 2023. 5. 16. 23:20

3년 전 취준 시절에 프론트엔드 개발자를 준비하면서 리액트를 아주 잠깐 공부한 적이 있다. 그 당시에도 리액트가 대세였는데 아직도 대세인 듯 하다.

지금 다니는 회사에서는 다른 프레임워크를 쓰느라 리액트를 다뤄보지 않았는데

며칠 전, 3년 만에 리액트를 써 볼 기회가 있었다. 그동안 정말 많은 게 달라져 있었다.

 

3년 전에 노마드 코더에서 리액트 강의를 수강했었는데 그 당시엔 클래스형 컴포넌트로 구현하는 실습을 하며 공부했던 기억이 있다. 요즘은 클래스형보단 함수형과 리액트 훅이 추세인 것 같았다.

(취준 때 리액트 관련 책도 샀었는데 프레임워크는 빨리 변한다는 소문에 취업하고 바로 팔았는데 정말 다행이다.)

 

함수형 컴포넌트를 사용하면 클래스형에서 사용하는 생명주기 메소드는 사용할 필요가 없고, 대신에 리액트 훅이란 걸 사용하고 있었다.

 

리액트를 함수형 컴포넌트로 구현하는 이유

1. 간결하다.

: 클래스형으로 구현하면 constructor, 생명주기 메서드 등등 많은 양의 코드가 필요한 반면에 함수형은 보다 직관적이고 간결한 코드를 짤 수 있다.

  • 클래스형 컴포넌트 예시
import { Component } from 'react';

class TestComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ...
    };
  }
  
  testFunc() {
    ...
  }

  render() {
    const { ... } = this.state;

    return (
      <div>
        ...
      </div>
    );
  }
}

export default TestComponent;
  • 함수형 컴포넌트 예시
import { useState } from 'react';

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

  const testFunc = () => {
    ...
  };

  return (
    <div>
      ...
    </div>
  );
};

export default TestComponent;

 

그리고 this.어쩌구 안써도 된다.

  • 클래스형 컴포넌트에서 내부 함수 구현
increment() {
  this.setState(prevState => ({
    count: prevState.count + 1
  }));
}
  • 함수형 함수 구현
const increment = () => {
  setCount(count + 1);
};

2. 테스트에 용이하다.

: 함수형이기 때문에 입출력이 뚜렷해서 검증이 용이하다.

 

등등의 장점이 있다. 일단 클래스형보다 훨씬 간결한 건 너무 장점이다.

 

리액트 훅(Hook)

리액트 훅을 안정적으로 사용하려면 리액트 패키지가 16.8.0 버전 이상이어야 한다.

그리고, 리액트 훅은 함수 컴포넌트에서만 사용할 수 있다.

리액트 훅은 그냥 함수이다. 'use~~어쩌구' 로 시작하는 함수

주로 사용하는 훅 함수는 useState, useEffect, useCallback, useMemo, useRef, useContext 등이 있다.

 

훅을 사용하기 위해선 리액트에서 사용할 함수를 임포트 해야 한다.

import { useEffect, useState } from 'react'

자주 쓰는 훅에 대해 간단히 설명하자면...

useState

const [value, setValue] = useState(0)

너무 편리했던 함수..!!

useState로 선언한 값의 상태가 변경되면 리렌더링된다. 값이 많아질수록 클래스에서 constructor 어쩌구 보다 가독성이 뛰어나다.

값을 변경할 땐 setValue(변경할 값)만 써주면 value값이 바뀌고 리렌더링된다.

setValue(1)

첨에 위 코드에서 선언했을 때 초기값을 0으로 해서 value는 0이었고 setValue로 value값을 1로 변경했다.

 

useEffect

useEffect는 콜백 함수와 의존성 목록을 매개변수로 받는다.

특정 값이 바뀔 때마다 콜백 함수를 실행하고자 할 때 의존성 목록 배열 안에 값을 넣어주면 된다.

useEffect(() => {
  ...
}, [value])

value값이 바뀔 때마다 콜백함수가 실행된다.

 

컴포넌트가 생성될 때 한 번만 실행하고 싶은 경우엔 의존성 목록에 빈 배열을 넣어준다.

useEffect(() => {
  ...
}, [])

 

컴포넌트가 생성될 때, 소멸될 때 실행하고 싶을 경우 ex) 타이머 return값을 주면 된다.

useEffect(() => {
  ...
  return () => {
  	...
  }
}, [])

 

useRef

useRef는 두 가지 경우에 사용한다.

 

1. 값이 변경되도 렌더링하고 싶지 않을 경우에 사용한다.

state로 인해 컴포넌트가 렌더링되어도 Ref의 값은 변하지 않는다.

const countRef = useRef(0);

countRef는 { current: 0 } 의 값을 갖게 되는데 countRef의 값을 변경하고 싶을 땐 countRef.current로 접근할 수 있다.

countRef.current += 1;

값은 변경되도 리렌더링되지 않으니 화면에서 countRef를 출력한다면 countRef를 변경해도 렌더링되지 않았기 때문에 값이 변하지 않을 것이다.

 

2. DOM 요소에 접근하기위해 사용한다.

리액트에선 가상 DOM을 사용하여 기존 자바스크립트에서 사용하던 DOM API를 사용할 수 없다. ref를 사용하면 DOM 요소에 접근할 수 있다.

 

 

등등 이외에도 여러 유용한 훅들이 있다.

(그건 다음에,,,)

 

 

어쨌든 훅을 써보니 편리하다는 장점이 있었는데 한편으론, 너무 리액트에 의존하는 느낌이었다.

순수 자바스크립트에는 없는 함수들이기 때문에 나중에 다른 프레임워크를 사용한다면 훅을 사용할 수 없으니..

훅을 사용하는 방법보단 원리를 이해하는 데에 더욱 집중해야 할 것 같다.