[React] 1. React Hook

2023. 3. 27. 15:52React

1. React Hook 이란?

Hook은 React 버전 16.8 부터 React 요소로 새로 추가되었습니다. Hook을 이용하여 기존 Class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 React의 기능을 사용할 수 있습니다.
Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 " 연동(hook into) " 할 수 있게 해주는 함수입니다. Hook은 class 안에서는 동작하지 않습니다. 대신 class 없이 React를 사용할 수 있게 해주는 것입니다.

1) Hook 을 사용했을 때 장점

(1) 더 빠른 성능과 짧은 코드 양

(2) Wrapper 컴포넌트양 감소

(3) 하나의 컴포넌트를 생명주기가 아닌 기능을 기반으로 하여 작은 함수 단위로 나뉠 수 있게 함.

 

2) Hook 을 사용했을 때 단점

(1) 호출되는 순서에 의존, hooks의 규칙을 따르기 위해 많은 리소스 필요.

(2) useEffect의 빈틈.

(3) 클로저에 의존적.

 

3) Hook 사용 규칙

- 최상위에서만 Hook을 호출해야 합니다. 반복문, 조건문, 중첩된 함수 내에서는 Hook을 실행할 수 없다.

- React 함수 컴포넌트 내에서만 Hook을 호출해야 한다.

 

2. React Hook 정리

1) useState()

상태 값과 그 값을 갱신하는 함수를 반환합니다.

(1) 기본 문법

const [state, setState] = useState(initialState);

● state : 상태 값 저장 변수명

● setState : 상태 값을 갱신하는 함수명

● initialState : 상태 값의 초기 값

(2) 예제

import React, {useState} from 'react';

function Example() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count+1)}>
        Click Me!
      </button>
    </div>
  );
}

export default Example;

 

2) useEffect()

컴포넌트가 렌더링될 때마다 특정 작업을 실행시키는 Hook입니다.

(1) 기본 문법

useEffect(callback, dependencyArray);

● callback : 컴포넌트가 렌더링될 때 실행시킬 함수.

● dependencyArray : 배열 값의 형태로 인수가 들어간다. 배열내의 값이 변경될 때마다 callback 함수가 실행된다.

// 1. dependencyArray 에 값이 있는 경우
useEffect(() => {
  // callback 함수
}, [count]) 

// 2-1. dependencyArray 가 빈 배열인 경우
useEffect(() => {
  // callback 함수
}, [])

// 2-2. dependencyArray 가 빈 배열인 경우
useEffect(() => {
  // callback
  return () => {
    // cleanup 
  }
}, [])

// 3. dependencyArray 가 없는 경우
useEffect(() => {
  // callback
})

- 1번 문법의 경우, count의 값이 변경될 때마다 callback 함수를 실행시킨다. 

- 2-1번 문법의 경우, 컴포넌트가 렌더링 되는 시점에서 단 한 번만 실행된다.

- 2-2번 문법의 경우, unmount 될 때 cleanup 함수가 실행되고, 특정 값을 넣어주면 특정 값이 update 될 때 마다 cleanup 함수를 실행 시킨다.

- 3번 문법의 경우, 컴포넌트가 렌더링 될 때마다 실행된다.

 

(2) 예제

import React, {useState} from 'react';

function Example() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    alert(`count 값은 : ${count}`);
    
    return () => alert(`unmount 상태의 count 값은 : ${count}`);
  }, [count])
  
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count+1)}>
        Click Me!
      </button>
    </div>
  );
}

export default Example;

- 위 예제에서 dependencyArray의 count 값을 지우고 비교해보는 것도 좋다.

3) useCallback()

메모이제이션된 콜백을 반환합니다. 그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경됩니다. 이것은 불필요한 렌더링을 방지하기 위해 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용합니다.

* Memoization(메모이제이션) : 계산된 값을 자료구조에 저장하고 이후 같은 계산을 반복하지 않고 자료구조에서 꺼내 재사용하는 것.

(1) 기본 문법

const memoizedCallback = useCallback(function, deps);

(2) 예제

import React, {useState, useCallback} from "react";

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

    const increase = useCallback(() => {
      setCount(count + 1)
    }, [count])

    return(
      <div>
        <p>{count}</p>
          <button onClick={increase}>
            Click Me!
          </button>
      </div>
    )
}

export default Example;

 

4) useMemo()

메모이제이션된 값을 반환합니다. 생성(create) 함수와 그것의 의존성 값의 배열을 전달하세요. useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산할 것입니다. 이 최저과는 모든 렌더링 시의 고비용 계산을 방지하게 해줍니다.

(1) 기본 문법

const example = useMemo(callback, dependancyArray);

(2) 예제

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

const Example : React.FC = () => {
  const [count, setCount] = useState(0);
  const [onOff, setOnOff] = useState(false);

  // const switchOnOff = onOff ? "On" : "Off"

  const switchOnOff = useMemo(() => {
    return (onOff ? "On" : "Off");
  }, [onOff])

  useEffect(() => {
    console.log(`useEffect 호출`)
  }, [onOff])

  return(
    <div>
      <input type="number" value={count} onChange={(e) => setCount(Number(e.target.value))}/>
      <p>{switchOnOff}</p>
      <button onClick={() => setOnOff(!onOff)}>Click Me!</button>
    </div>
  )
}

export default Example;

useEffect를 사용하여 의존성 배열(dependencyArray)에 onOff 값을 넣어도 count의 state가 변경될 때마다 useEffect의 콜백 함수가 실행된다. 그 이유는 자바스크립트에서 객체는 원시 타입과는 다르게 값이 저장될 때 주소 값으로 저장되기 때문이다. 그렇기 때문에 React에서 count state가 바뀌면 App 컴포넌트가 재호출되고, switchOnOff의 주소 값도 변경이 되기 때문에 switchOnOff가 변경 되었다고 판단한다.

let obj = {};
console.log(obj === {}) // false;

 위와 같은 현상을 방지하기 위해 사용하는 것이 useMemo Hook 이다.

5) useRef()

useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지될 것입니다.

(1) 기본 문법

(2) 예제 1 - DOM 요소에 접근

import React, {useEffect, useRef} from "react";
  
const Example = () => {
  const inputRef = useRef();

  useEffect(() => {
    console.log(inputRef);
    inputRef.current.focus();
  }, [])

  const loginAlert = () => {
    alert(`환영합니다. ${inputRef.current.value}`);
    inputRef.current.focus();
  }
  return (
    <div className="App">
      <header className="App-header">
        <input ref={inputRef} type="text" placeholder="id"/>
        <button onClick={loginAlert}>Login</button>
      </header>
  </div>
  );  
}
  
export default Example;

(3) 예제 2 - 변수 관리

import React, {useRef} from "react";

const Example = () => {

  const count = useRef(0);

  function increaseCount(){
      count.current += 1;
      console.log(count.current) // 1, 2, 3 ...
  }

  return (
    <>
     <button onClick={increaseCount}>count</button>
    </>
  );
};

export default Example;

 

3. 참고 사이트

1) https://ko.reactjs.org/docs/hooks-intro.html

 

Hook의 개요 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

2) https://velog.io/@jaewoneee/React-React-Hooks-%EC%A0%95%EB%A6%AC

 

[React] React Hooks 정리

ing

velog.io

3) https://developerntraveler.tistory.com/146

 

[React] React Hooks의 장단점

React Hooks는 ReactConf 2018에서 발표된 새로운 기능으로 16.8 버전부터 새로 추가되었다. Hooks를 이용하면 class 없이 state와 여러 React의 기능을 사용할 수 있다. Hooks는 왜 필요한가? Hooks의 등장 배경은

developerntraveler.tistory.com

4) https://velog.io/@jinyoung985/React-useMemo%EB%9E%80

 

[React] useMemo란?

📋 useMemo란? useMemo는 리액트에서 컴포넌트의 성능을 최적화 하는데 사용되는 훅이다. useMemo에서 memo는 memoization을 뜻하는데 이는 그대로 해석하면 ‘메모리에 넣기’라는 의미이며 컴퓨터 프로

velog.io

5) https://itprogramming119.tistory.com/entry/React-useRef-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C