• 티스토리 홈
  • 프로필사진
    루루개발자
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
루루개발자
  • 프로필사진
    루루개발자
    • 분류 전체보기 (212)
      • react & next.js (12)
      • Node.js & Javascript & Type.. (24)
        • d3.js (10)
      • 차트 만들기 (1)
      • 티스토리 스킨 개발 (7)
      • 내가 만든 패키지 (3)
      • 내가 만든 CSS (1)
      • CSS (7)
      • 도커 & 쿠버네티스 (3)
      • 개인 프로젝트 (7)
      • 리뷰 & 추천 (2)
      • 알고리즘 (1)
      • IT 기타 (18)
      • 잡동사니 (1)
      • Spring Boot (5)
      • 취미로 그리는 그림들 (120)
      • 개인적인 생각들 (0)
  • 반응형
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • useState 에 대해 알아봅시다
        2023년 07월 24일
        • 루루개발자
        • 작성자
        • 2023.07.24.오후11:04
        반응형

        안녕하세요. 루루개발자 입니다.

        리액트로 프론트엔드 개발을 하다보면 자주 접하는 훅 함수가 있습니다. 바로 "useState" 입니다. 

         

        useState 란 무엇인가?

        useState 는 리액트에서 기본으로 제공해주는 훅 함수들 중 하나로, 컴포넌트에 상태 변수를 추가할 수 있도록 해주는 훅 함수입니다. 해당 함수는 2개의 원소를 갖는 배열이 반환되며, 첫번째 원소에는 상태 값이 반환되며 두번째 원소에는 상태 값을 변경할 때 사용되는 setter 함수가 반환되게 됩니다. 그렇기 때문에 보통 아래와 같이 구조 분해 할당을 이용하여 선언하게 됩니다.

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

         

        상태값 변경시 리렌더링 발생

        useState 에서 반환된 배열의 두번째 값인 setter 함수를 호출하면 상태 값을 변경할 수 있고, 렌더링이 다시 진행됩니다.

         

        상태값 변경은 비동기적으로 동작

        useState 의 setter 함수를 호출한 이후 바로 다음 줄에서 해당 state 값을 참조하면 아직 바뀌기 이전 state 가 참조됩니다. 이는 useState 의 setter 함수가 비동기적으로 동작하기 때문인데, setter 함수의 인자에 새로운 값이나 업데이터 함수를 전달하게 되면 바로 그 값으로 상태가 업데이트 되는 것이 아니라 그 값이나 업데이터 함수는 대기열에 들어가게 됩니다. 그리고 렌더링이 진행될 때 대기열에 들어가 있던 값으로 상태가 업데이트 되거나, 업데이터 함수가 호출되어 상태가 업데이트 됩니다.

         

        업데이터 함수로 상태를 변경해야 하는 경우

        setter 함수의 인자에는 값을 넣을 수도 있지만, 업데이터 함수를 넣을 수도 있습니다. 업데이터 함수는 인자에 prev 값이 넘어오면서 next state 값이 반환되게 되어 있도록 정의된 함수입니다. 업데이터 함수를 사용해야 하는 경우는 바로 이전 값을 참조해야 하는 경우입니다.

        const [number, setNumber] = useState(0);
        
        useEffect(() => {
          setNumber(prev => prev + 1);
          setNumber(prev => prev + 1);
          setNumber(prev => prev + 1);
          setNumber(prev => prev + 1);
          setNumber(prev => prev + 1);
        }, []);

        위 코드를 실행해보면 number 는 5로 바뀌어 있는 것을 확인 할 수 있습니다. 업데이터 함수 자체도 인자에 이전 상태 값을 받아올 수 있지만, 업데이터 함수들 끼리도 이전에 호출된 업데이터 함수에서 반환된 상태 값을 이전 상태 값으로 참조할 수 있습니다. 즉 이전 값이 반드시 필요한 상태 업데이트 같은 경우에는 업데이터 함수를 사용하면 됩니다.

         

        state 값이 바뀌고 다시 렌더링되기 까지 걸리는 시간

        상태 값이 바로 바뀌는 것이 아니라면, 바뀌고 렌더링이 완료된 시점까지 얼마나 걸릴까 궁금하여 직접 한번 아래 코드로 테스트를 진행해보았습니다.

        "use client"
        
        import { useEffect, useState } from "react";
        
        export default function Page() {
          const [number, setNumber] = useState(0);
        
          useEffect(() => {
            console.log(`[${performance.now()}] 렌더링 완료됨.`);
          }, [number]);
        
          return (
            <>
              { 
                (function() {
                  console.log(`[${performance.now()}] component return 됨.`);
                  return <></>;
                })() 
              }
              <div className="w-full relative">
                현재 number 값 : { number }
              </div>
              <button
                onClick={() => {
                  console.log(`[${performance.now()}] setNumber 호출됨.`);
                  setNumber(prev => prev + 1);
                }}>
                number 값을 1 증가시키기
              </button>
            </>
          );
        }

        위 코드를 실행해본 결과 로그는 다음과 같이 표시되었습니다.

        밀리세컨드가 표시되고 있는데 state 값은 1ms 내외로 변경되는 것 같았습니다. 물론 이는 PC 사양과 개발 환경에 따라 충분히 달라질 수 있는 수치 입니다. 지속적으로 테스트해본 결과 제가 테스트를 진행했을 때는 1ms ~ 2ms 정도 소요됨을 확인하였습니다.

         

        짧은 시간안에 setter 함수를 연속적으로 호출 시 렌더링은 1번만 진행

        만약 다음과 같이 setter 함수를 연속적으로 호출 했을 경우 렌더링은 1번만 진행됩니다. 

        "use client"
        
        import { useEffect, useState } from "react";
        
        export default function Page() {
          const [number, setNumber] = useState(0);
        
          useEffect(() => {
            setNumber(prev => prev + 1);
            setNumber(prev => prev + 1);
            setNumber(prev => prev + 1);
            setNumber(prev => prev + 1);
            setNumber(prev => prev + 1);
          }, []);
        
          useEffect(() => {
            console.log(`[${performance.now()}] 렌더링 완료됨. number => ${number}`);
          }, [number]);
        
          return (
            <>
              { 
                (function() {
                  console.log(`[${performance.now()}] component return 됨.`);
                  return <></>;
                })() 
              }
              <div className="w-full relative">
                현재 number 값 : { number }
              </div>
            </>
          );
        }

         

        리액트에서는 배치 상태 업데이트라고 하여 짧은 시간 이내에 setter 함수가 연속적으로 호출 되었을 경우에는 호출 된 값 또는 업데이터 함수들을 큐에 집어 넣어 놓고 대기합니다. 그리고 그 짧은 시간이 지난 후 큐에 집어 넣은 것들을 순차적으로 일괄적으로 호출(적용) 하기 시작합니다. 이러한 배치 상태 업데이트 방식을 채택하고 있으므로, setter 함수를 연속으로 호출해도 렌더링은 1번만 발생시키는 것이 가능합니다. 이 짧은 시간이 정확히 얼마 만큼의 시간인지에 대해서는 리액트 공식 문서에서는 찾아 볼 수 없었는데 (있는데 제가 못찾은 것일 수도 있습니다.) 추후 찾게 되면 본 글에 업데이트 하도록 하겠습니다.

         

         

         

        - 출처 - 

        https://react.dev/reference/react/useState

         

        반응형

        'react & next.js' 카테고리의 다른 글

        Next.js 가 실행될 때 한번만 특정 로직을 실행하는 방법  (2) 2023.10.17
        useEffect 에 대해 알아봅시다  (0) 2023.07.25
        Next.js 의 렌더링 과정에 대하여  (0) 2022.11.09
        Next.js 에서 local, development, production 환경 셋팅하기  (0) 2022.10.13
        자식 컴포넌트에 전달하는 props 관련 테스트  (0) 2022.05.29
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
      • useState 란 무엇인가?
      • 상태값 변경시 리렌더링 발생
      • 상태값 변경은 비동기적으로 동작
      • 업데이터 함수로 상태를 변경해야 하는 경우
      • state 값이 바뀌고 다시 렌더링되기 까지 걸리는 시간
      • 짧은 시간안에 setter 함수를 연속적으로 호출 시 렌더링은 1번만 진행
      • 안녕하세요
      • 감사해요
      • 잘있어요

      티스토리툴바

      단축키

      내 블로그

      내 블로그 - 관리자 홈 전환
      Q
      Q
      새 글 쓰기
      W
      W

      블로그 게시글

      글 수정 (권한 있는 경우)
      E
      E
      댓글 영역으로 이동
      C
      C

      모든 영역

      이 페이지의 URL 복사
      S
      S
      맨 위로 이동
      T
      T
      티스토리 홈 이동
      H
      H
      단축키 안내
      Shift + /
      ⇧ + /

      * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.