React Hooks

issol·2021년 2월 5일
0

Learned

목록 보기
2/2

내가 React의 매력에 빠지게 해준 React Hook에 대해 공부한 내용을 정리하고자 한다. 실제로 프로젝트에서도 많이 사용했기 때문에 예시도 많이 들 수 있을 것 같다.

React Hook 이 뭔데??

함수 컴포넌트에서 React state와 Lifecycle 기능을 연동할 수 있게 해주는 함수

왜 등장했을까?

  1. 클래스형 컴포넌트에선 Logic의 재사용이 어렵다! => state관리나 부분적으로 api사용에 대한 처리가 재사용할 시 제약이 너무 많다.
  2. constructor, this, binding 등 기본 rule을 따르지 않으면 경고메시지나 에러가 나기 때문에 꼭 지켜줘야된다! => 이 점 때문에 코드가 길어지고 복잡해진다.

이런 문제점 때문에 함수형 컴포넌트를 사용하기 위해 Hook이 만들어졌다!

그럼 Hook들은 어떻게 사용해?

React 공식문서에 기재된 Hook들은 기본 Hook들은
기본 useState useEffect useContext
추가 useReducer useCallback useMemo useRef useImperativeHandle useLayoutEffect useDebugValue가 있는데 이중에서 내가 사용했던 useState, useEffect, useReducer를 다뤄보려한다.

useState

import React, { useState } from 'react';

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

 return (
   <div>
     <p>{count}</p>
     <button onClick={() => setCount(count + 1)}>Click</button>
   </div>
 );
};

useState는 사용자의 인터랙션에 따라 바뀌는 값에 대한 상태관리를 해주는 Hook이다.
const[count, setCount] => 처음 원소값은 현재 상태이고, 그 다음 원소값은 setter함수이다.
useState(0) => useState 대괄호 안의 값은 초기값이다.

useEffect

componentDidMount

useEffect(()=>){
  console.log("마운트됐을때");
}
useEffect(()=>){
  console.log("마운트됐을때(처음만실행)");
, [] }

둘의 차이는 뒤에 []로 들어간 deps이다.
deps를 생략한다면 rerendering 될 때마다 명령을 수행한다.
만약 deps에 빈 배열이 있다면 최초 화면이 render됐을때만 useEffect안에 명령어를 수행한다.

componentDidUpdate

useEffect(()=>){
  console.log("업데이트 됐을때!(deps값이)");
,[바뀌는값] }

특정 값이 업데이트 될 때 명령어를 수행하고 싶다면 deps에 검사하고 싶은 값을 넣어준다.
단, 이럴 경우 최초 render시에도 명령이 수행되기 때문에 useRef를 사용하여 조절할 수 있다.

const mounted = useRef(false);
useEffect(()=>){
  if(!mounted.current){
  	mounted.current = true;
  }else{
  	//todo
  }
,[바뀌는값]}

componentWillUnmount

useEffect(()=>){
  console.log("마운트됐을때");
  return ()=>{
    console.log("cleanup");
  } 
,[]}

cleanup함수 반환 (useEffect에 대한 뒷정리함수이다.)

  • unmount될 때만 cleanup을 하고 싶다면 deps에 빈 배열을 넣는다.
  • 특정값이 업데이트되기 직전에 cleanup을 하고 싶다면 deps에 검사하고 싶은 값을 넣는다.

useReducer

const TestReducer = () => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      <h2>{state.count}</h2>
      <button onClick={() => dispatch({ type: "INCREMENT", step: 1 })}>
        증가
      </button>
      <button onClick={() => dispatch({ type: "DECREMENT", step: 1 })}>
        감소
      </button>
    </>
  )
}

state로 현재 상태를 불러오고, 각 버튼이 클릭되면 dispatch 함수가 실행되게 설정되어있습니다.
dispatch의 type은 증가나 감소, step은 얼마나 증가, 감소시킬지에 대한 값을 넘긴다.

function reducer(state, action) {
  switch (action.type) {
    case "INCREMENT":
      return { count: state.count + action.step }
    case "DECREMENT":
      return { count: state.count - action.step }
    default:
      throw new Error("Unsupported action type:", action.type)
  }

reducer에서는 count의 초기값 설정해주고, type에 따라 증가, 감소 명령을 수행해준다. 여기서 state는 현재 상태이고, action은 dispatch할때 넘어온 값들이다.

redux를 사용하기 때문에 useReducer를 적극적으로 활용하여 사용하였다.
다음번엔 redux와 redux-saga에 대해 써볼까 한다.

참고사이트 - useState, useEffect
참고사이트 - useReducer

profile
Junior Front-End Developer

0개의 댓글