React Hooks - useState

post-thumbnail

1. useState 복습

  • (1) 정의 useState는 가장 기본적인 hook이며, 함수 컴포넌트에서 가변적인 상태를 가지게 해줍니다. 그래서 우리가 저번 기초 주차에서 useState를 활용해서 카운터 프로그램도 만들어보고, Todo list로 만들어보았죠?
  • (2) 복습해볼까요? 🔥 useState의 기본적인 형태는 아래 처럼 생겼습니다.
    const [state, setState] = useState(initialState);
    그동안 배열로 감싸진 모습에 처음에는 익숙하지 않으셨을텐데요. 원래는 useState 라는 함수가 배열을 반환하고, 이것을 구조 분해 문법으로 꺼내놓은 모습일 뿐입니다. 우리는 state를 변수로 사용했고, setState를 이용해서 state 값을 수정할 수 있었습니다. 그리고 만약 state가 원시 데이터타입이 아닌 객체 데이터 타입인 경우에는 불변성을 유지해줘야 한다고 이미 배웠습니다.

2. 함수형 업데이트

  • (1) 함수형 업데이트란? setState를 사용하는 방식에는 우리가 알고 있는 방식이 아닌 또 다른 방식이 있습니다. 함수형 업데이트 방식 입니다.
    // 기존에 우리가 사용하던 방식
    setState(number + 1);
    
    // 함수형 업데이트 
    setState(() => {});
    위 코드와 같이 setState의 ( ) 안에 수정할 값이 아니라, 함수를 넣을 수 있습니다. 그리고 그 함수의 인자에서는 현재의 state을 가져올 수 있고, { } 안에서는 이 값을 변경하는 코드를 작성할 수 있습니다. 마치 아래 코드와 같이 말이죠.
    // 현재 number의 값을 가져와서 그 값에 +1을 더하여 반환한 것 입니다.
    setState((currentNumber)=>{ return currentNumber + 1 });
  • (2) 두 방식의 차이점은? 일반 사용법과 함수형 업데이트 방식의 차이점이 무엇일까요? 두개의 코드를 비교해봅시다. 먼저 일반 업데이트 방식으로 onClick안에서 setNumber(number + 1) 를 3번 호출했습니다. number가 1씩 증가하는군요.
    // src/App.js
    
    import { useState } from "react";
    
    const App = () => {
      const [number, setNumber] = useState(0);
      return (
        <div>
    			{/* 버튼을 누르면 1씩 플러스된다. */}
          <div>{number}</div> 
          <button
            onClick={() => {
              setNumber(number + 1); // 첫번째 줄 
              setNumber(number + 1); // 두번쨰 줄
              setNumber(number + 1); // 세번째 줄
            }}
          >
            버튼
          </button>
        </div>
      );
    }
    
    export default App;
    이번에는 함수형 업데이트 방식으로 동일하게 작동시켜보겠습니다. number가 3씩 증가하네요.
    // src/App.js
    
    import { useState } from "react";
    
    const App = () => {
      const [number, setNumber] = useState(0);
      return (
        <div>
    			{/* 버튼을 누르면 3씩 플러스 된다. */}
          <div>{number}</div>
          <button
            onClick={() => {
              setNumber((previousState) => previousState + 1);
              setNumber((previousState) => previousState + 1);
              setNumber((previousState) => previousState + 1);
            }}
          >
            버튼
          </button>
        </div>
      );
    }
    
    export default App;
    왜 다르게 동작할까요? 일반 업데이트 방식은 버튼을 클릭했을 때 첫번째 줄 ~ 세번째 줄의 있는 setNumber가 각각 실행되는 것이 아니라, 배치(batch)로 처리합니다. 즉 우리가 onClick을 했을 때 setNumber 라는 명령을 세번 내리지만, 리액트는 그 명령을 하나로 모아 최종적으로 한번만 실행을 시킵니다. 그래서 setNumber을 3번 명령하던, 100번 명령하던 1번만 실행됩니다. 반면에 함수형 업데이트 방식3번을 동시에 명령을 내리면, 그 명령을 모아 순차적으로 각각 1번씩 실행시킵니다. 0에 1더하고, 그 다음 1에 1을 더하고, 2에 1을 더해서 3이라는 결과가 우리 눈에 보이는 것이죠.

3. 왜 리액트팀은 useState가 위 방식으로 동작하도록 만들었을까?

  • (1) 공식문서의 설명 📢 리액트는 성능을 위해 setState()를 단일 업데이트(batch update)로 한꺼번에 처리할 수 있습니다. 공식문서의 설명처럼, 불필요한 리-렌더링을 방지(렌더링 최적화)하기 위해 즉, 리액트의 성능을 위해 한꺼번에 state를 업데이트 한다고 하네요.
  • (2) 손님-웨이터-주방 비유 자, 손님이 **피자, 콜라, 피클**을 주문한다고 합시다. 웨이터는 손님이 피자! 콜라! 피클! 하나씩 말할 때 마다 주방으로 달려가진 않아요. 손님이 세 가지의 주문을 모두 완성했을 때, 그 때 한꺼번에 주방으로 갑니다. 그래야 동선이 가장 짧으니까요.

4. 정리

  • useState의 업데이트 방식은 2가지 방식이 있으며, 각각 다르게 동작한다.
  • useState 로 원시데이터가 아닌 데이터를 변경할때는 불변성을 유지해야 한다.
profile
𝙸 𝚊𝚖 𝚊 𝚌𝚞𝚛𝚒𝚘𝚞𝚜 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚠𝚑𝚘 𝚎𝚗𝚓𝚘𝚢𝚜 𝚍𝚎𝚏𝚒𝚗𝚒𝚗𝚐 𝚊 𝚙𝚛𝚘𝚋𝚕𝚎𝚖. 🇰🇷👩🏻‍💻

0개의 댓글