[React] setState의 동작 원리, prevState

이주희·2022년 4월 2일
1

React ♥️ Next.js

목록 보기
17/48

setState의 스코프 안에서 해당 state를 다룰 때는 조심해야 한다....
왜냐하면........

1. setState의 동작 원리

1) state가 바뀌면 화면 전체가 자동으로 다시 그려진다. (리렌더링)
참고로 let은 값이 바뀌어도 다시 렌더링 하지 않는다.

2) setState비동기로 작동한다. = state의 값은 setState가 호출되는 시점이 아닌, 해당 코드가 들어있는 함수가 모두 실행된 이후에 바뀐다.

💡 Why?
setState가 비동기가 아닌 동기로 작동하게 되면 변경될 때마다 바로바로 렌더링이 일어나서 비효율적이기 때문이다.


함수 안에 setState가 여러개 있으면
함수 하나를 실행시키는데 렌더링을 여러번 하게 되어서 성능상 좋지 않다.

따라서 임시 저장소에 모아두었다가 코드를 끝까지 읽고 한번에 바꿔서 렌더링 한다.


👆🏻 if문 위에 setMyWriter가 있어도, if문에서는 아직 writer에 값이 들어가있지 않은 상태이다. 그래서 isActive가 true로 바뀌지 않는다.

BoardWrite.Container에서는
즉각적으로 값을 읽어서 if문을 돌리기 위해서 event.target.value를 사용했다.


리렌더가 되는 상황

  1. 새로운 props가 들어올 때
  2. 부모 컴포넌트가 렌더링 될 때
  3. 강제 업데이트(forceUpdate)가 실행될 때
  4. state가 변경될 때

이해가 잘 안돼서 돌려본 코드!

import { useState } from "react";
export default function stateTest() {
  const [value1, setValue1] = useState(0);

  const onClick1 = () => {
    setValue1(value1 + 1); // 지금 value1은 0
    setValue1(value1 + 1); // 여기도 value1은 0
    setValue1(value1 + 1); // 여기도!!! value1은 0
    console.log("value1: " + value1);
    console.log("value1: " + value1);
    console.log("value1: " + value1);
  };

  return (
    <div className="App">
      <button onClick={onClick1}>+</button>
      <h1>value1 : {value1}</h1>
      <h1>value1 : {value1}</h1>
      <h1>value1 : {value1}</h1>
    </div>
  );
}

setValue1(value1 + 1) 을 세번 하더라도, 이 함수 안에서 가지고 있는 value1의 값은 항상 0이기 때문에 첫번째 setValue1에서도, 두번째 세번째에서도 결과는 1이 된다.

onClick1이 한번 더 실행되면 이제 함수가 한번 끝났으므로, setValue1(value1 + 1)이 한번 실행되어서 value1에는 1이 들어가있고, 이 함수가 종료되면 value1에 1을 더한 2가 들어가게 된다.

setState

 const onClickCount = () => {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
  };
  • 위 함수가 실행되면 count를 증가시키는 setCount가 4개나 있음에도 불구하고 count의 값은 1만 증가된다.

  • 변경된 값이 바로 반영되는 것이 아니고 임시 저장공간에 넣어두고, 함수가 끝나고 나서 값이 변경되기 때문이다ㅜㅜ


prevState

  • 이럴 때 prev를 사용하면 임시 저장공간에 있는 값을 가져올 수 있다!!

  • 임시 저장공간에 값이 없으면 default 값을 가져온다.

  • (prev) 대신 (prevState)로 써도 된다.

  • 리렌더는 동일하게 함수가 종료되고 나서 한번만 일어난다.

  const [count, setCount] = useState(0);
  const onClickCount = () => {
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
  };
  • 이렇게 prev를 이용해야 count의 값이 setCount로 증가시킨 횟수만큼 증가한다.

prevState 활용

  • boolean 값을 변경시킬 때 편리하게 활용할 수 있다.
  const [isOpen, setIsOpen] = useState(false);

  const onToggleModal = () => {
    setIsOpen((prev) => !prev);
  };
profile
🍓e-juhee.tistory.com 👈🏻 이사중

0개의 댓글