본문 바로가기
Web Study/원티드 프리온보딩 4월 FE

React Hooks - useState, useEffect

by 쿠리의일상 2023. 4. 1.

Hook?

함수 컴포넌트에서 리액트 state 와 생명주기 기능을 연동할 수 있게 해주는 함수를 의미 (class 없이 리액트를 사용할 수 있게 해주는 것)

 

Hook 은 React 버전 16.8부터 리액트 요소로 새로 추가 되었다.

Hook 을 사용하여 기존 class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 리액트의 기능을 사용할 수 있다.

 

Hook 은 props, state, context, refs, lifecycle 과 같은 리액트 개념에 좀더 직관적인 api 를 제공해준다.

생명주기 메서드를 기반으로 쪼개는 것보다 훅을 통하여 서로 비슷한 것을 하는 작은 함수를 묶음으로 컴포넌트를 나누는 방식이 직관적으로 이해하기 용이하다.

https://ko.reactjs.org/docs/hooks-overview.html

 

Hook 개요 – React

A JavaScript library for building user interfaces

ko.reactjs.org



Hook 사용 규칙

  • 최상위에서만 Hook 을 호출해야 한다. -> 반복문, 조건문, 중첩된 함수 내에서 Hook 을 실행하지 말아야 한다.
  • 리액트 함수 컴포넌트(+직접 작성한 custom Hook) 내에서만 훅을 호출해야 한다. 일반 자바스크립트 함수에선 훅을 호출해선 안된다.

 

import React, { useState } from 'react';

function Example() {
  // "count"라는 새로운 상태 값을 정의합니다.
  const [count, setCount] = useState(0);

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

State Hook

- useState(초기값)

배열 구조 분해 문법으로 현재 state 값과 이 값을 업데이트 하는 함수를 쌍으로 제공한다. 

class 컴포넌트의 this.setState와 거의 유사하지만 이전 state와 새로운 state 를 합치지 않는다는 차이점이 존재

 

 

Effect Hook

리액트 컴포넌트 안에서 데이터를 가져오거나 구독하고 DOM을 직접 조작하는 작업을 통틀어 side effects 라고 한다.

이러한 동작은 다른  컴포넌트에 영향을 줄 수도 있고 렌더링 과정에서 구현할 수 없는 작업이기 때문이다.

- useEffect

함수 컴포넌트 내에서 side effects 를 수행할 수 있게 해준다.

side effects 란 컴포넌트가 렌더링 된 이후에 비동기로 처리되어야 하는 부수적인 효과를 의미

즉, 렌더링이 될 때마다 특정 작업을 수행할 수 있도록 설정해주는 것

 

클래스 컴포넌트의 componentDidMount, componentDidUpdate, componentWillUnmount 와 같은 목적으로 제공되지만 useEffect 하나의 API로 통합된 것이다.

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

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

  // componentDidMount, componentDidUpdate와 비슷합니다
  useEffect(() => {
    // 브라우저 API를 이용해 문서의 타이틀을 업데이트합니다
    document.title = `You clicked ${count} times`;
  });

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

리액트는 DOM 을 바꾼 뒤, effect 함수를 실행한다.

effect 는 컴포넌트 안에 선언되어 있기에 props 와 state 에 접근할 수 있으며 기본적으로 리액트는 매 렌더링 이후에 effect 를 실행해준다.

useEffect(콜백함수, 콜백함수를 실행시킬 조건 배열);

 

useEffect를 리렌더링 될 때마다 실행하고 싶을 때

useEffect(콜백함수);

useEffect 를 Mount 될 때만 실행하고 싶을 때

함수의 두번째 파라미터로 비어있는 배열을 넣어주면 된다.

useEffect(콜백함수, []);

 

특정 값이 업데이트(state, props 변경) 될 때 실행하고자 하면 (이는 Mount와 Update 둘다 실행됨)

useEffect(콜백함수, [검사하고 싶은 값]);

두번째 파라미터로 전달되는 배열 안에 검사하고 싶은 값을 넣어주면 된다.

검사하고 싶은 값에는 useState 를 통하여 관리하고 있는 상태나, props 로 전달 받은 값을 넣어줘도 무관하다.

Mount 될 때를 제외하고 Update 될 때만 실행시키고 싶다면

const mounted = useRef(false);
useEffect( () => {
	if(!mounted.current) {
    	mounted.current = true;
    } else {
    	console.log('업데이트될 때마다 실행');
    }
}, [검사해줄 값]);

 

컴포넌트가 Unmount 될 때 

useEffect는 함수를 반환할 수 있는데, 이 함수를 cleanup 이라고 한다.

사라질 때 cleanup 함수를 실행시키고 싶다면 return 에 콜백함수와 검사해줄 값에는 빈 배열을 넣어주면 된다.

useEffect(() => {
	return () => {
    	console.log('cleanUp 함수');
    };
}, []);

 

useEffect 는 기본적으로 렌더링 되고난 직후마다 실행되며 두번째 파라미터 배열에 무엇을 넣느냐에 따라 실행되는 조건이 달라진다.
특히나 useEffect 안에 state 나 props 가 있다면, 조건 배열에 넣어주는 것이 규칙이다. 만약 해당 값을 넣어주지 않는다면 useEffect 안의 함수가 실행될 때 최신 상태, props 를 가리키지 않을 수 있기 때문이다!!