setState()

정혜인·2023년 2월 3일
0

react

목록 보기
5/14
post-thumbnail

리액트 처음부터 기초를 다지던 중, event handling을 공부하다가 state 관련해서 제대로 정의를 할 수 없다는 것을 깨닫고 setState부터 공부해보았다.

💦 setState()

리액트의 함수형 컴포넌트 내에서 상태를 관리하기 위해 사용하는 hooks인 useState()를 통해 반환되는 함수

✅ setState() 특징

  1. 기본적으로 비동기로 동작
  2. setState()를 연속적으로 호출 했을 때 리액트가 내부적으로 batch 처리
  3. setState()에 state 객체를 넘겨줄 수 있을 뿐만 아니라 새로운 state를 반환하는 함수도 인자로 전달 가능

❓ 2. setState()를 연속적으로 호출 했을 때 리액트가 내부적으로 batch 처리 ?

import react, {useState} from "react";
import "./App.css";

export default function App() {
  const [number, setNumber] = useState(1);

  const addOne = () => setNumber(number+1); //1을 더해주는 함수
  const subtractOne = () => setNumber(number - 1); //1을 빼주는 함수
  const multiplyBy2 = () => setNumber(number*2); //2를 곱해주는 함수
  const multiplyBy2AndAddBy1 = () => {
    multiplyBy2();
    addOne();
  }; // 2를 곱하고 1을 더해주는 함수

  return (
    <div className="outer-wrapper">
      <h1>Number : {number}</h1>
      <div className="btn-wrapper">
        <button onClick={addOne}>+ 1</button>
        <button onClick={subtractOne}>- 1</button>
        <button onClick={multiplyBy2}>*2</button>
        <button onClick={multiplyBy2AndAddBy1}>*2 + 1</button>
      </div>
    </div>
  );

};

위의 예시에서, addOne 함수, subtractOne 함수, multiplyBy2 함수는 제대로 동작하지만,

multiplyBy2AndAddBy1 함수를 실행시키면 addOne()만 실행된다. (문제 발생)

💡 setState()는 비동기이기 때문!!

📛 비동기?

변경되기 전의 state 값과 변경된 후의 state 값을 비교

( = 현재의 state 값으로 만든 element tree와 업데이트된 state값으로 만든 element tree를 비교)

한 후에, 최종적으로 변경된 부분이 있으면 그 부분만 DOM에 적용

⏩ 어쨌든 setState()는 비동기 방식인데, 효율성을 위해 setState()는 모든 object들을 merging한 후 *한번만* 호출한다.

즉, 위의 예시처럼 setState()를 연속적으로 사용했을 때에는 마지막에 사용된 함수만 적용되는 것처럼 보이는 것!


❣ 해결방법

setState()를 연속적으로 사용할 수 있게 하는 방법을 알아보자. (두번째 코드 참고)

//변경 전
const addOne = () => setNumber(number+1); 
const subtractOne = () => setNumber(number - 1); 
const multiplyBy2 = () => setNumber(number*2);

const multiplyBy2AndAddBy1 = () => {
    multiplyBy2();
    addOne();
  };

🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽

//변경 후
const addOne = () => setNumber(number => number+1); 
const subtractOne = () => setNumber(number => number - 1); 
const multiplyBy2 = () => setNumber(number => number*2);

const multiplyBy2AndAddBy1 = () => {
    multiplyBy2();
    addOne();
  };

위의 코드에서는 multiplyBy2AndAddBy1()을 실행하면 addOne()만 실행되지만,

아래의 코드에서는 multiplyBy2AndAddBy1()을 실행하면 multiplyBy2()와 addOne() 모두 잘 동작한 결과를 볼 수 있다.

💥변경된 점

인자를 준 뒤에 state를 반환하도록 하였다.

addOne()함수 : number를 인자로 주고, number+1이라는 state를 반환하는 함수

setNumber(number => number+1)

넘겨받은 인자의 함수를 Queue에 저장해두는 방식이다.

위의 예시에서는 multiplyBy2() 함수를 먼저 실행해주고, number*2라는 새로운 값을 반환한 뒤 그 다음 함수(addOne)의 인자로 넘겨주는 것이다.

→ 결론적으로 비동기라는 점은 변함 없지만, 동기적으로 처리해주는 것처럼 보인다.

0개의 댓글