[React] State & Rerender

0 0 0

React가 언제 다시 렌더링되는지, state를 바꿀 때 주의할 점을 정리합니다.


1. React Rerender

코드가 많아질수록 렌더링도 많아지므로 최적화가 중요합니다.

  • 부모 컴포넌트 렌더링

    • 부모 컴포넌트가 렌더링되면 자식 컴포넌트도 모두 다시 렌더링됩니다.
  • state 변경

    • React는 state 변경을 감지하면 다시 렌더링합니다.
    • state를 직접 수정하면 React가 변경을 감지하지 못합니다.
    • useEffect로도 확인해 봤지만, 직접 수정한 값은 감지되지 않았습니다.
  • props 변경

    • 전달받은 props가 바뀌면 다시 렌더링됩니다.

React 리렌더링 조건



2. React prevState

React는 state를 변경해도 바로 반영하지 않고, 함수의 코드를 끝까지 실행한 뒤 다시 렌더링합니다.

import {useState} from 'react'

export default function CounterStatePage() {
    const [Count, setCount] = useState(0);

    function onClickCountUp(){
        setCount(Count+1)
        setCount(Count+2)
        setCount(Count+3)
        setCount(Count+4)
        setCount(Count+5)
    }
    function onClickCountDown(){
        setCount(Count-1)
    }

    return (
        <>
            <div>{Count}</div> // 5
            <button onClick={onClickCountUp}>카운트 증가!!!</button>
            <button onClick={onClickCountDown}>카운트 감소!!!</button>
        </>
    )
}

setCount()를 여러 번 호출해도 최종 Count는 15가 아니라 5가 됩니다.

setCount(Count+1) => 0 + 1
setCount(Count+2) => 0 + 2
setCount(Count+3) => 0 + 3
setCount(Count+4) => 0 + 4
setCount(Count+5) => 0 + 5

// result :  Count = 5

다시 렌더링되기 전까지 state 변경은 임시로 모아 두는데, 이때 각 호출이 같은 이전 값을 기준으로 계산하기 때문에 마지막 호출의 결과만 반영됩니다. 마지막 호출이 +1이었다면 Count는 1만 증가했을 것입니다.

setCount(Count+1) => 0 + 1
setCount(Count+2) => 0 + 2
setCount(Count+3) => 0 + 3
setCount(Count+4) => 0 + 4
setCount(Count+5) => 0 + 5
setCount(Count+1) => 0 + 1

// result :  Count = 1

이를 방지하려면 이전 state 값(prev)을 받아서 계산하는 방법을 씁니다.

function onClickCountUp(){
  setCount((prev) > prev +1) 0 + 1 = 1
  setCount((prev) > prev +2) 1 + 2 = 3
  setCount((prev) > prev +3) 3 + 3 = 6
  setCount((prev) > prev +4) 6 + 4 = 10
  setCount((prev) > prev +5) 10 + 5 = 15
}
// result : 15

prev를 사용하면 앞선 변경이 반영된 값을 기준으로 계산하기 때문에 모든 호출이 누적됩니다.



3. React Lifting-State-Up

React의 데이터 흐름은 단방향입니다. 그래서 형제 컴포넌트가 같은 state를 공유하려면 state를 한 단계 위(부모)로 올려서 관리하는데, 이것을 Lifting State Up이라고 합니다.

Child1에서 카운트를 증가시키면 5가 전달되고, Child2에서 증가시키면 1이 전달됩니다.

부모가 각 자식에게서 받은 값을 저장한 뒤, 다시 자식 컴포넌트에 내려 보여 줍니다.

댓글 0