처음 써 본 리액트 훅(Hook) 후기..
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 요소에 접근할 수 있다.
등등 이외에도 여러 유용한 훅들이 있다.
(그건 다음에,,,)
어쨌든 훅을 써보니 편리하다는 장점이 있었는데 한편으론, 너무 리액트에 의존하는 느낌이었다.
순수 자바스크립트에는 없는 함수들이기 때문에 나중에 다른 프레임워크를 사용한다면 훅을 사용할 수 없으니..
훅을 사용하는 방법보단 원리를 이해하는 데에 더욱 집중해야 할 것 같다.