동행큐브
729
2021-02-20 15:26:17
3
223

리액트 리렌더링 관련해서 질문 있습니다.


현재 TimeTest라는 컴포넌트가 있습니다. 해당 컴포넌트가 렌더링 되자마자 렌더링되고나서부터 몇초가 지났는지를 실시간으로 보여주는 컴포넌트 입니다. 

useEffect로 시작할때 함수를 실행시키고, setInterval로 1초마다 second를 +1하게 합니다. 

아래는 해당 코드입니다. 

import React, {useEffect, useState} from 'react';
import SonTest from "./SonTest";


const TimeTest = () => {
    const [second, setSecond] = useState(0);

    useEffect(() => {
        setInterval(() => {
            console.log(second);
            setSecond(second + 1);
            console.log(second);
        }, 1000)
    }, [])


    return (
        <>
            <div>
                {second}
                <SonTest/>
            </div>
        </>
    );
}

export default TimeTest;


저는 제대로 짰다고 생각했는데 second가 0에서 1로 넘어가고 2로는 안넘어가더라고요. 

console.log()로 찍어봤는데 setSecond 하기 전과 후 모두 0으로 똑같았습니다. 

뭐가 잘못된걸까요?


그리고 현재 TimeTest 컴포넌트 하위에 SonTest 컴포넌트가 있는데, TimeTest가 리렌더링 되면 SonTest도 리렌더링 되면서 SonTest에 있는 상태값 중 useState()로 선언된 상태값은 그대로 보존이 되나요? 아니면 useState() 안에 있는 초기값으로 변하나요?

0
  • 답변 3

  • 킁킁탐정
    844
    2021-02-20 15:40:57

    이 문제는 second 상태 변수의 스코프 문제입니다. 간단한 해결책은 setSecond(s => s + 1) 처럼 사용하시면 정상적으로 동작합니다. 그리고 useState()로 선언된건 보존됩니다. 다시 렌더링되는 여부는 props/states 그리고 컴포넌트 내부에서 사용한 리터럴 객체 같은것으로 인해 결정됩니다.


  • Frudy
    7k
    2021-02-20 16:46:21

    혹시 eslint 안쓰시고계신가요? 저같은경우에 저렇게 코드를 짜면,

    useEffect의 dependency 목록에 second라는걸 추가하라고 경고를 보여주거든요.

  • 동행큐브
    729
    2021-02-22 13:10:04

    도움 많이 되었습니다. 감사합니다. 

    esLint는 얘기를 많이 들어봤는데 한번 알아보야겠네요. 감사합니다. 

  • 로그인을 하시면 답변을 등록할 수 있습니다.