ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] setInterval을 통해 React Hooks 알아보기 (useEffect, useState, useRef)
    개발 여정/FrontEnd 2023. 5. 26. 22:39

     

      setInterval을 통해 React Hooks 알아보기 (useEffect, useState, useRef)

     

    JS의 setInterval은 특정 시간마다 코드를 실행시키도록 하는 메소드다. setInterval(코드, 시간)

    이를 이용해 useEffect, useState, useRef와 같은 리액트 훅들의 차이를 살펴볼 수 있다.

     

     

    setInterval을 통해 1초마다 값을 더하는 페이지를 만들어보자.

    브라우저 화면과 콘솔창에 갱신되는 값을 출력하고자 한다. 

     

    useEffect, useState 쓰기

    export default function Timer() {
      const [count, setCount] = useState(0); // useState로 state 값을 0으로 설정해준다.
    
      useEffect(() => {
        setInterval(() => { // setInterval 함수를 통해 1초마다 count 값이 +1 증가하도록 한다.
          console.log(count); // console에도 count값이 찍히도록 한다.
          setCount(count + 1); // useState에 있는 count를 가져다 쓴다.
        }, 1000);
      }, []); // 의존성 배열에 빈 값을 줘서 렌더링될 때마다 값이 초기화되도록 한다.
    
      return <p>{count}</p>;
    }

    결과값을 보면 1초마다 +1 씩 증가하게 했지만 1만 렌더링되고, 콘솔에는 초기값인 0만 여러 번 찍히는 것을 볼 수 있다.

    의존성 배열에 빈 배열을 줬기 때문에 렌더링될 때마다 값이 초기화되서, setCount(0 + 1)이 1초마다 반복된 것이다.

     

    그러면 의존성 배열에 count 값을 주면 되지 않을까..? 

    다음과 같이 의존성 배열에 count 값을 넣어줘 보자.

     

    export default function Timer() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        setInterval(() => { 
          console.log(count); 
          setCount(count + 1); 
        }, 1000);
      }, [count]); // 의존성 배열에 count 값 주기
    
      return <p>{count}</p>;
    }

     

    그러면 의존성 배열 안의 count 값 변경과 useEffect 안의 count 값 변경이 동시에 일어나면서 무한루프에 빠지게 된다.

    렌더링이 지직이는 것은 물론이고, 브라우저에 부하를 일으켜 나중엔 먹통이 된다.

     

     

    setState에 로컬 콜백함수 넣기

    setCount에 count 값이 아닌, 로컬 콜백함수를 넣는다.

    그러면 밖에 있는 useState에서 값을 가져오는 것이 아니라, setCount 내에서 state를 갱신하기 때문에 화면은 정상적으로 출력된다.

    import React, { useState, useEffect } from "react";
    
    export default function Timer() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        setInterval(() => {
          console.log(count);
          setCount((prev) => prev + 1); // 이전 state 값에 1을 더하는 콜백함수를 넣는다.
        }, 1000);
      }, []);
    
      return <p>{count}</p>;
    }

    하지만 콘솔에서는 count 값을 여전히 0으로 출력한다는 것을 볼 수 있다.

    만약 콘솔에서도 1초씩 변화하는 값을 보고 싶다면..?

     

     

    useRef() 함께 쓰기

    useRef()는 공식 문서 상에는 컴포넌트 생애 주기에 상관없이 state가 현재 값을 가질 수 있도록 하는 훅이라고 설명되어 있다.

    쉽게 설명하면, 컴포넌트 변화와 상관없이 특정 값이 변경될 수 있도록 하는 훅이다.

    useRef는 컴포넌트에 영향을 받지 않고 값을 변경시킬 수 있지만, 반대로 useRef의 값이 변해도 컴포넌트는 렌더링되지 않는다. 따라서 useRef는 렌더링 시 이용하는 것이 아니라, 콘솔 확인이나 alsert 알림, 조건문 등에 사용하는 것이 적합하다.

     

    import React, { useState, useEffect, useRef } from "react";
    
    export default function Timer() {
      const [count, setCount] = useState(0);
      const value = useRef(0);
    
      useEffect(() => {
        setInterval(() => {
          console.log(value.current); // value의 현재 값인 vaule.current를 가져오도록 한다.
          setCount((prev) => prev + 1);
          value.current++; // value.current에 1씩 더한다.
        }, 1000);
      }, []);
    
      return <p>{count}</p>;
    }

    useRef의 .current를 이용해 콘솔에서도 1초마다 변화하는 값을 확인할 수 있다.

     

     

     

    Reference

    https://velog.io/@dogfoot/React-useState-useRef-%EC%B0%A8%EC%9D%B4

    https://lwamuhaji.tistory.com/60

    https://ye-yo.github.io/react/2022/01/21/setInterval%EC%82%AC%EC%9A%A9%EB%AC%B8%EC%A0%9C.html

Designed by Tistory.