개발 노트

React - 함수형 업데이트 본문

React

React - 함수형 업데이트

알 수 없는 사용자 2023. 1. 3. 09:15

setState의 비동기적 특성 vs 함수형 업데이트

 

setState는 비동기로 동작한다.

리액트는 효율적으로 렌더링하기 위해 여러개의 상태 값 변경 요청을 batch(일괄 처리)처리하기 때문이다.

왜?? 성능 이슈 때문이다. -> setState마다 리렌더링이 일어난다면 얼마나 많은 렌더링이 일어날지 가늠할 수가 없다.

  const onClick = () => {
  	//value = 0
    setValue(value+1)
    //value + 1 => 2
    setValue(value+1)
    //value + 1 => 2
    setValue(value+1)
    //value + 1 => 2
  }

위의 setState는 변경된 사항을 기억하지 않기 때문에 마지막 업데이트 적용되어 다름 렌더링에 쓰이게 된다.

 

setState 함수형 업데이트

setState를 동기적으로 사용하는 방법은 없을까? => 함수형 업데이트를 사용하자.

  const onClick = () => {
    setValue(prev => prev+1)
    setValue(prev => prev+1)
    setValue(prev => prev+1)
  }
  
  	//A : 이번 렌더링 초기(시작) state 값
	//B : A 또는 이번 렌더링에서 업데이트된 값 / 다음 렌더링에 사용될 값
	//C : 함수형 업데이트를 통해 생겨난 값
    
    	// A = 0
	// B = A = 0

	setValue(prev => prev+1)
	// ①-1 : C = B + 1 => 1 
	// ①-2 : C 를 B 에 저장

	setValue(prev => prev+1)
	// ②-1 : C = B + 1 => 2
	// ②-2 : C 를 B 에 저장

	setValue(prev => prev+1)
	// ③-1 : C = B + 1 => 3
	// ③-2 : C 를 B 에 저장

함수형 업데이트는 이렇게 업데이트된 값을 저장하기 때문에 여러번의 업데이트가 적용되어 다음 렌더링에 사용된다.

 

함수형 업데이트를 한 상태를 다른 useState 에서 어떤 값이 사용될까?

고민 코드

 const onClick = (e) => {
    setValueX(prev => prev + 1);
    setValueX(prev => prev + 1);
    setValueY(valueX + 1)
  }

  return (
    <div className="App"  >
      <button onClick={onClick}>+</button>
      <h1>valueX : {valueX}</h1>
      <h1>valueY : {valueY}</h1>
    </div>
  );
}
  • 이 코드에서 '+'버튼을 클릭하면 valueY는 어떤 값을 보여줄까?
  • valueX 의 2가지 상태
    A : 이번 렌더링의 초기(시작) state 값
    B : 저장하여 다음 렌더링에 사용될 state 값

따라서 2가지의 경우가 나온다
case 1. A(0) + 1 = 1
case 2. B(2) + 1 = 3

  • case 1이 정답이다. valueY 는 1으로 나온다
  • Y 는 업데이트된 X의 값이 아닌 X의 이번 렌더링 초깃값을 사용하게 사용함을 의미한다.

설명

용어 정리

  • X useState -
    A : 이번 렌더링 초기(시작) state 값 = 0
    B : A 또는 이번 렌더링에서 업데이트된 값 / 다음 렌더링에 사용될 값
    C : 함수형 업데이트를 통해 생겨난 값
  • Y useState -
    D : 이번 렌더링의 초기(시작) state 값
    E : 저장하여 다음 렌더링에 사용될 state 값
setValueX(prev => prev + 1);
// ①-1 처음 setState 시 B는 A => B = 0 
// ①-2 C = B(0) + 1 = 1 
// ①-3 C 를 B에 저장
// ①-4 B = 1

setValueX(prev => prev + 1);
// ②-1 C = B(1) + 1 = 2
// ②-2 C 를 B에 저장 
// ②-3 B = 2  

setValueY(valueX + 1)
// ③-1 E = A + 1 = 1

 

여러 개의 useState를 업데이트했다면 과연 렌더링은 몇번 일어날까?

문제 : input에 a 를 input 에서 작성하여 1번의 onChange가 호출되었을 때 몇 번의 render 가 일어날까?

코드

export default function App() {
  const [valueX, setValueX] =  useState(0)
  const [valueY, setValueY] =  useState(0)
  const [valueZ, setValueZ] =  useState(0)

  const onChange = (e) => {
    setValueX(prev => prev + 1);
    setValueY('')
    setValueZ(e.target.value);
  }

  return (
    <div className="App"  >
     <input onChange={onChange}/>
      <h1>valueX : {valueX}</h1>
      <h1>valueY : {valueY}</h1>
      <h1>valueZ : {valueZ}</h1>
    </div>
  );
}

  • 1번의 렌더링만 일어난다.
  • setState가 호출되면 리렌더링이 되긴 하지만 그 즉시 리렌더링이 일어난 것이 아닌 JS Call Stack 이 모두 실행되고 리렌더링이 일어난다. 한꺼번에 setState들의 업데이트가 이루어지며 리렌더링 되는 것이다.

관련 자료 출처 : https://velog.io/@tjdgus0528/React-Native-5x048oii

'React' 카테고리의 다른 글

React 로그인 1 - 세션을 이용한 로그인 인증  (0) 2023.01.24
AntDesign - Form  (0) 2023.01.20
개행, let vs State  (0) 2022.12.29
React - Ant design Charts  (0) 2022.12.23
React-antdesign table 컬럼 높이 값 바꾸는 방법  (0) 2022.12.23