React 훅(Hook) 사용하기

사용 전 알아야 할 것

React 컴포넌트의 생명주기

  • 리액트의 컴포넌트는 라이프 사이클(생명주기)가 존재한다.
  • 라이프 사이클은 Mounting(생성 될 때), Updating(업데이트 할 때), Unmounting(제거 할 때) 세가지로 나뉜다.
    Mounting : DOM이 생성되고 웹 브라우저에 나타나는 것을 마운트라고 한다.
    Updating : 컴포넌트가 업데이트 될 때를 말하며 props, state가 바뀌거나 부모 컴포넌트가 리렌더링, 혹은 forceUpdate 함수를 통해 강제로 렌더링 시킬때 등에 의한 상황에서 발생한다.
    Unmounting : 컴포넌트가 DOM에서 제거하는 과정을 언마운트라고 한다.
  • "리액트 라이프사이클" 이라고 검색하면 나오는 유명한 그림이다.
  • 그림에는 클래스형 컴포넌트와 함수형 컴포넌트의 사용되는 타이밍이 나타나있다.
  • 이 링크를 클릭하면 해당 그림이 있는 페이지를 볼 수 있다. 이 페이지의 각 박스를 클릭하면 공식문서로 이동하며 해당 함수에 대한 설명을 볼 수 있다.

Hook이란 무엇인가?

  • 공식문서에 있는 설명을 보면 Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 "연동(hook into)"할 수 있게 해주는 함수라고 한다.
  • Hook은 class 안에서는 동작하지 않고, 대신 class 없이 React를 사용할 수 있게 해주는 것이라고 한다.
  • react 라이브러리에서 import 하여 사용하며 컴포넌트 내부 최상단에서 선언하고 사용할 수 있다.

자주 사용되는 Hooks

useState

const [상태이름, 상태를 변경할 함수 이름] = useState(초기값);

  • 상태(동적인 값)를 관리할 때 사용한다.
  • 값을 변경할 때 절대 상태를 직접 변경하는 것이 아닌 상태변경 함수에 값을 전달하는 방식으로 변경한다. (불변성)
import { useState } from 'react';

function AddCounter() {
  const [number, setNumber] = useState(0);
  
  const addCount = () => {
    setNumber(number + 1);	//number++ 같이 상태를 직접변경하면 안된다.
  }
  
  return (
    <div>
      <span>{number}</span>
      <button onClick={addCount}>증가버튼</button>
    </div>
  );
}

export default AddCounter;
  • 컴포넌트에 버튼을 클릭하게 되면 addCount 함수가 실행되며 상태가 업데이트 된다.
  • 컴포넌트가 리렌더링 되며 number가 업데이트 되고 화면에 업데이트된 number가 나타나게 된다.

useReducer

const reducer = (state, action) => {
  //첫번째 인자는 상태, 두번째 인자는 상태변경 함수에 들어가는 인자이다.
  switch(action.type) {
    case '더하기':
      return state + 1;	//상태변경 로직
    case '빼기':
      return state - 1;	//상태변경 로직
    default:
      return state;
  }
};

const initialState = 0;

const [state, dispatch] = useReducer(reducer, initialState);

dispatch({ type: '더하기' });	//사용하기, type은 action에 들어가게 된다.
  • useState와 비슷하게 상태를 관리할 때 사용한다.
  • useState와 다른 점은 상태 업데이트 로직을 컴포넌트에서 분리시킬 수 있다.
  • 단순한 값을 관리할 때는 useState를 사용하고
    복잡한 로직이나 여러 값을 관리할 때에는 useReducer를 사용한다.

useRef

  • 특정 DOM을 선택할 때 사용한다.
  • 컴포넌트와 별도로 변수를 관리할 때 사용한다.

특정 DOM 선택

import { useRef } from 'react';

function InputComponent() {
  const textInput = useRef();
  
  const focusTextInput = () => {
    textInput.current.focus();	//DOM이 선택되어 focus() 함수를 사용할 수 있다.
  }
  
  return (
    <>
      <input ref={textInput} />	//ref 속성값으로 useRef() 변수값으로 지정
      <button onClick={}></button>
    </>
  )
}

export default InputComponent;
  • 태그 속성 refuseRef()로 지정한 변수값을 넣는다.
  • 변수명.current 를 통해 접근 할 수 있다.

컴포넌트와 별도로 변수 관리

import { useState, useRef } from 'react';

function App() {
  const [components, setComponents] = useState([
    {
      id: 1,
      value: "1번 입니다."
    }
  ]);
  
  const nextId = useRef(2);	//초기 값 지정
  
  const addComponent = () => {
    setComponents([...components,
        { 
          id: nextId.current, 
          value: `${nextId.current}번 입니다.` 
        }
    ]);
    
    nextId.current++;	//직접 변수를 변경해준다.
  }
  
  return (
    <>
      {components.map(v => <span key={v.id}>{v.value}</span>)}
    </>
  )
}

export default App;
  • useRef로 지정한 값은 컴포넌트가 리렌더링 되어도 값이 변하지 않는다.
  • 직접 값을 변경하는 작업을 거쳐도 값이 변하게 되며 이때 컴포넌트 또한 리렌더링 되지 않는다.

useEffect

const effect = useEffect(() => { 
  //mount 혹은 update 전에 사용할 코드
  
  return () => { //cleanup 함수 (함수를 반환)
    //unmount 혹은 update 후에 사용할 코드 
  }; 
}, [deps]);
  • 마운트/언마운트/업데이트시 할 작업 설정할 때 사용한다.
  • deps에 의존 할 값을 넣는다.
    이 곳에 들어간 값이 변하면 업데이트 전, 후에 동일한 작업을 수행하게된다.
  • deps에 빈 배열을 넣게되면 mount, unmount의 작업만 수행하게 된다.

useMemo

const memo = useMemo(() => {
  const calc = value * 2;
  //이곳에 계산 코드를 넣는다.
  
  return calc;	//값을 리턴한다. memo를 호출하면 value 값을 리턴한다.
}, [value])	//deps
  • 이전에 계산한 값을 재사용할 때 사용한다.
  • deps에 의존할 값을 넣으면 해당 값이 변할 때 마다 useMemo 또한 새로 연산된다.
  • deps에 빈 배열을 넣으면 mount 시 한번만 연산된다.

useCallback

const func = useCallback((param) => {
  alert(param + value);
}, [value]);	//deps

func(5);	//사용예시
  • useMemo를 기반으로 만들어졌다.
  • 특정 함수를 재사용 하고싶을 때 사용한다.
  • depsuseMemo와 동일.




내용 참고 : 벨로퍼트와 함께하는 모던 리액트

좋은 웹페이지 즐겨찾기