Hooks는 리액트 v16.8에 새로 도입된 기능으로 함수형 컴포넌트에서도 상태 관리를 할 수 있는 useState
, 랜더링 직후 작업을 설정하는 useEffect
등의 기능을 제공하여 기존의 함수형 컴포넌트에서 할 수 없었던 다양한 작업을 할 수 있게 해준다.
새로 작성하는 컴포넌트는 되도록 클래스형 컴포넌트 보다는 훅을 사용해서 함수형 컴포넌트로 작성하도록 한다.
함수형 컴포넌트에 비해 가지는 단점들에도 불과하고, 그 동안 클래스형 컴포넌트를 사용했던 이유는 state
관리나 Life Cycle method
의 사용 때문이었다. 복잡하고 뚱뚱하지만 클래스의 힘을 빌려야만 React가 원활하게 작동할 수 있었던 것이다.
그런데 Hooks
의 등장으로 인해 함수형 컴포넌트에서도 이러한 클래스형 컴포넌트의 작업들을 할 수 있게 되었다. 기존의 클래스형 컴포넌트가 가지고있던 복잡성, 재사용성의 단점들 까지 해결 하면서 밀이다. 특히나 OOP를 선호하지 않는 개발자에게 있어서 React를 함수 중심으로 사용할 수 있게 되었다는 것은 매우 환영할 만한 일이다.
리액트 컴포넌트는 Class형 컴포넌트
와 Function형 컴포넌트
로 나뉜다.
기존의 개발방식은 일반적으로 함수형 컴포넌트를 주로 사용하되 state이나 Life Cycle method를 사용해아 할 때에만 클래스형 컴포넌트를 사용하는 방식이었다.
이유는 Class형 컴포넌트가 Function형 컴포넌트에 비해 가지는 단점 때문이다.
1. 코드가 길고 복잡하다.
constructor, this, binding 등 지켜야 할 규칙이 많아서 코드가 복잡하고 길어진다.
JAVA처럼 OOP(object-oriented programming)의 테크닉을 수려하게 적용하지는 않으면서도 근본은 클래스의 모습을 띄고있다. 클래스 자체가 Life Cycle metho로 인해 기본적으로 뚱뚱하다.
2. Logic의 재사용이 어렵다.
클래스형 컴포넌트에서는 High-Order Component(HOC)로 컴포넌트 자체를 재 사용 할 수는 있지만 부분적으로 DOM 관련 처리나 API사용 및 state을 다루는 등의 logic에 있어서는 경우에 따라 같은 로직을 2개 이상의 Life Cycle method에 중복해서 넣어야 하는 등 재 사용에 제약이 따른다.
3. 성능
리액트 측에서 2015년 10월에 '향후'에 함수형 컴포넌트의 performance를 상승 시킬것이라고 발표한 바 있다. 하지만 이후에 실제 상승 결과를 언급한적은 없다. 다만 함수형 컴포넌트의 performance우위를 측정한 글들을 종종 볼 수 있다. 대략 6%~45%상승 했다고 말한다.
기본적은 틀은 다음과 같다.
import React from 'react';
class App extends React.Component{
render(){
return (
<div style ={{textAlign :"center"}}>
<div style = {{fontSize : "100px" }}> 0 </div>
</div>
);
}
}
export defalut App;
여기에 숫자를 state로 선언하고 클릭하면 숫자를 1씩 증가시키는 버튼과 1씩 감소시키는 버튼을 각각 만들어 보겠다.
import React from 'react';
class App extends React.Component{
state = {
number=0
};
render(){
return (
<div style ={{textAlign :"center"}}>
<div style = {{fontSize : "100px" }}> {this.state.number} </div>
<button onClick = {this.handleClickIncrement}> 더하기 </button>
<button onClick = {this.handleClickDecrement}>빼기 </button>
</div>
);
}
handleClickIncrement =() => {
this.setState (state => ({
number:state.number +1
}));
};
handleClickDecrement = () => {
this.setState(state => ({
number:state.number -1
}));
};
}
export defalut App;
숫자를 다루기 위해 컴포넌트에 state를 선언하고, 더하는 함수 handleClickIncrement
에서도 this.setState()메소드
를, 빼는 함수에는 hadleClickDecrement
에서도 this.setState()메소드
를 사용했다.
이번에는 같은 기능을 리액트 hooks의 useState
을 사용해서 구현해 보겠다.
import React from 'react';
const App =() => {
const [number, setNumber] = useState(0);
return (
<div style ={{textAlign :"center"}}>
<div style = {{fontSize : "100px" }}> {number} </div>
<button onClick = {() => setNumber(number +1)} >더하기 </button>
<button onClick = {() => setNumber(number -1)} >뺴기 </button>
</div>
);
}
}
export defalut App;
우선 코드가 많이 줄어든 것을 볼 수가 있다.
useState
는 클래스형 컴포넌트의 state의 선언과 관리를 짧고 직관적인 코드로 가능하게 해주는 Hooks 이다. number라는 state과 setNumber라는 state변경 함수를 useState를 통해 선언하였다.
useState에 관한 자세한 설명은 아래 글을 참고하면된다.
클래스형 컴포넌트에서 setState을 사용하여 state을 변경할 때에는 shallow copy로 인해 항상 새로운 객체를 생성해서 전달해줘야하는 불편함이 있었는데, useState을 사용하여 얻은 함수 (setNumber)에서는 원하는 값을 인자로 전달하기만 하면 된다. state의 선언과 변경 과정이 매우 간소화 된것을 느낄수가 있다.
위의 예시에서는 사용하지 안았지만 useState와 같은 hook들을 필요한 곳에 사용함으로써 Logic의 재사용이 가능하게 된다. 물론 useState, useEffect, useReducer등은 react에 내장되어있는 hook이지만, 당연히 우리가 우너하는 기능을 담당하는 커스텀 hook을 만들어서 재 사용할 수 도있다.
참고
https://codingbroker.tistory.com/23
https://yeri-kim.github.io/posts/react-hooks/
[서적]리액트를 다루는 기술