[React] Hooks #1

GyungHo Go·2020년 5월 24일
0

react hooks

목록 보기
1/1
post-thumbnail

Hooks

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%상승 했다고 말한다.

Class형 컴포넌트

기본적은 틀은 다음과 같다.

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()메소드를 사용했다.

Function형 컴포넌트 with Hooks

이번에는 같은 기능을 리액트 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에 관한 자세한 설명은 아래 글을 참고하면된다.

https://codingbroker.tistory.com/29

클래스형 컴포넌트에서 setState을 사용하여 state을 변경할 때에는 shallow copy로 인해 항상 새로운 객체를 생성해서 전달해줘야하는 불편함이 있었는데, useState을 사용하여 얻은 함수 (setNumber)에서는 원하는 값을 인자로 전달하기만 하면 된다. state의 선언과 변경 과정이 매우 간소화 된것을 느낄수가 있다.

위의 예시에서는 사용하지 안았지만 useState와 같은 hook들을 필요한 곳에 사용함으로써 Logic의 재사용이 가능하게 된다. 물론 useState, useEffect, useReducer등은 react에 내장되어있는 hook이지만, 당연히 우리가 우너하는 기능을 담당하는 커스텀 hook을 만들어서 재 사용할 수 도있다.

Hooks 장점

  • 재사용 가능한 롲직을 쉽게 만들 수 있다. 리액트의 내장 훅과 다른 사람들이 만든 여러 커스텀 훅을 레고처럼 조립해서 쉽게 새로운 훅을 만들 수 있다.
  • 훅을 하용하면 같은 로직을 한곳으로 모을 수 있어서 가독성이 좋다.

Hooks 사용 시 지켜야 할 규칙

  • 하나의 컴포넌트에서 훅을 호출하는 순서는 항상 같아야 한다.
  • 훅은 함수형 컴포넌트 또는 커스텀 훅 안에서만 호출 되어야 한다.
    - 우리가 useState 훅에 전달한 정보는 상탯값의 기본값 밖에 없다. 리액트가 age와 name 상태값을 구분할 수 있는 유일한 정보는 훅이 사용된 순서이다.

참고
https://codingbroker.tistory.com/23
https://yeri-kim.github.io/posts/react-hooks/
[서적]리액트를 다루는 기술

profile
기록하는 습관

0개의 댓글