훅. 후훅. 리. 리액트 훅. 후훅. 훅. 리. 리액트 훅 알아보기

DANO PARK·2022년 5월 24일
3

무작정 따라하기

목록 보기
6/9
post-thumbnail
post-custom-banner

What is React Hook?

React 16.8버전부터 새롭게 추가된 Hook은 기존 class를 사용하지 않고, React state와 lifecycle features를 연동할 수 있게 해주는 함수다.

기존 class를 사용한 React는 코드의 재사용성이 낮고, 작성하기 까다로우며, reloading이 신뢰하기 어렵다.

이러한 class가 가진 문제들을 함수형 컴포넌트 기능을 사용해 해결할 수 있는데, 함수형 컴포넌트는 state나 lifecycle을 직접 다룰 수 없다.

Hook은 함수형 컴포넌트가 class 컴포넌트의 역할을 할 수 있게 해준다.

useState

import React, { useState } frome 'react';
const [value, setValue] = useState(initialValue);

useState()는 함수형 컴포넌트에서도 가변적인 state를 지닐 수 있게 하는 Hook이다. useState()는 길이가 2인 배열을 반환하는데, 첫번째는 상태 값, 두 번째는 상태를 업데이트하는 함수이다.

initalValue는 초깃값으로 최초 렌더링 시에 한 번 사용된다. 해당 함수에 파라미터를 넣어 호출하면, 전달받은 바라미터 값이 바뀌고 컴포넌트는 정상적으로 리렌더링된다.

아래는 useState()를 사용해 만든 카운트업 예제

import React, { useState } from 'react';

export default function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      {`count: ${count}`}
      <button onClick={() => setCount(prev => prev + 1)}>+</button>
    </div>
  )
}

useRef

import React, { useRef } from 'react';
const valueRef = useRef(initalValue);

자바스크립트의 querySelector() 또는 getElememtById() 같이 DOM을 선택할때 사용하는 Hook이다.

React 컴포넌트에서 state는 상태를 바꾸는 함수를 호출한 이후 업데이트 된 상태를 조회할 수 있으나, useRef()를 사용할 경우 바로 조회가 가능하다.

아래는 useState()useRef()로 input에 입력한 value를 리셋하고 input 창을 포커싱하는 예제.

import React, { useState, useRef } from 'react'

export default function Practice09() {
  const input = useRef(null);
  const [text, setText] = useState("");

  const handleClick = () => {
    setText("");
    input.current.focus();
  }
  
  return (
    <div>
      <span>현재 value는 { text }입니다.</span><br />
      <input type="text" ref={ input } value={ text } onChange={(e) => setText(e.target.value)} />
      <button onClick={handleClick}>RESET</button>
    </div>
  )
}

useEffect

import React, { useEffect } from 'react';
useEffect(() => {}, []);

컴포넌트가 렌더링 될 때마다 특정 작업을 실행하게 하는 Hook.

useEffect()의 매개변수는 익명함수와 빈배열 두 가지 요소를 가진다. 배열은 빈 배열일때 처음 렌더링에만 실행되며, 값이 있으면 특정 상태 값이 업데이트 될 때만 실행된다. 마지막으로, 아예 배열이 생략된다면 리렌더링 될때마다 실행된다.

컴포넌트가 언마운트 되기전 또는 업데이트 직전 어떤 작업을 수행하고 싶다면, clean-up 함수를 반환해야한다.

clean-up 함수는 컴포넌트가 마운트 되기 전과 업데이트 전에 실행되며, 업데이트 전에 실행될 경우 업데이트 직전 state 값에 접근이 가능하다.

아래는 useState()useEffect()를 사용해 input 값이 3초 뒤 나오게 하는 예제로, useEffect()에 clean-up 함수를 넣어 value 값이 마지막 값으로만 나오게 설정했다.

import React, { useState, useEffect } from 'react'

export default function App() {
  const [value, setValue] = useState('');
  const [num, setNum] = useState("값을 입력하세요.");
  const [res, setRes] = useState("");
  useEffect(() => {
    if (value === "") {
      return setNum("값을 입력하세요.")
    } else {
      const a = setTimeout(() => setNum("3초 뒤 실행됩니다."), 0);
      const b = setTimeout(() => setNum("2초 뒤 실행됩니다."), 1000);
      const c = setTimeout(() => setNum("1초 뒤 실행됩니다."), 2000);
      const d = setTimeout(() => setNum("실행 완료"), 3000);
      const e = setTimeout(() => setRes(value), 3000);
      return () => {
        clearTimeout(a);
        clearTimeout(b);
        clearTimeout(c);
        clearTimeout(d);
        clearTimeout(e);
      }
    }
  }, [value]);
  return (
    <>
      <input 
        type="number"
        onChange={(e) => {setValue(e.target.value)}}
      />
      <br />
      { num }
      <br/>
      {`예상 값: ${ value }`}
      <br />
      {`출력 값: ${ res }`}
    </>
  )
}

useMemo

import React, { useMemo } from 'react';
const memoizationValue = useMemo(() => 함수, 배열);

React에서 컴포넌트의 렌더링은 계속해서 일어나고 있다. 간단한 구조라면 무리없이 재렌더링이 가능할 것이다. 그러나 복잡한 수식을 계산하는 등 리턴 값이 수초 이상 걸리는 구조라면 재렌더링할때마다 해당 수식이 다시 계산되는 일이 발생하며 UI에 지속적으로 지연이 발생된다.

이같은 상황은 memoization 기법을 활용하면 해결할 수 있다.

memoization은 기존에 수행한 연산의 결과값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기법을 말한다. 중복 연산을 피할 수 있기 때문에 성능을 최적화할 수 있다는 장점이 있다.

useMemo()는 두 개의 인자를 받는다. 첫 번째는 결과값을 생성해주는 팩토리 함수이며, 두 번재는 기존 결과값을 재활용하는 입력값 배열이다.

useCallback

import React, { useCallback } from 'react';
const callBackValue = useCallback(() => 함수, 배열)

useCallback()은 함수를 memoization된 값을 반환하여 계속해서 동일한 값을 보내주는 역할을 한다.

useCallback()은 두 개의 인자를 가지며, 첫 번째는 인라인 콜백, 두 번째는 의존성 값의 배열을 받게 된다. 배열에 변경을 감지해야할 값을 넣어주면, 등록한 함수가 변경될 때마다 새로운 콜백함수를 생성하게 된다.

이것은 최적화된 자식 컴포넌트에 props로 콜백 함수를 내려줄 때 유용하다.

useMemo()는 memoization된 값을 반환하여 동일 계산 반복수행을 최소화시켜주는 반면, useCallback()은 memoization된 콜백을 반환하여 새로운 함수가 생성되는 것을 줄이는 역할을 한다는 차이점이 있다.

끝.

profile
단오해서 단호박!
post-custom-banner

0개의 댓글