[React]-useState를 이용해 카운터를 만들어보자!

badassong·2023년 4월 4일
0

React

목록 보기
26/56
post-thumbnail

counter.jsx라는 컴포넌트를 만들고 useState를 이용해 버튼을 클릭할 때마다 숫자가 1씩 증가하게 만들어보았다.

Counter.jsx

import React, { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div className="counter">
      <span className="number">{count}</span>
      <button
        className="button"
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Add +
      </button>
    </div>
  );
}

그런데 여기서 든 의문점 하나!
왜 setCount(count++)로 쓰면 에러가 날까?

그 이유는 위에서 count를 const로 선언해주었기 때문이다.
상수는 재할당이 안되기 때문에 count++ 이 아니라 count+1로 써줘야 한다!
count++은
count=count+1 과 같은 의미이다. 이는 곧 count를 재할당 해주는 것이기 때문에 에러가 나는 것이다!

그럼 여기서 또 하나의 의문점!
setCount를 다섯번 호출하면 count값이 5가 될까??

setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);

정답은 NO!

이건 js의 클로저(closure)개념과 관련이 있는데, 클로저란 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다. 이를 조금 더 간단히 말하면 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다!

onClick이 호출됐을 때 전달되는 콜백 함수가 호출될 때 찰칵! 하고 현재 상태를 스냅샷한다. 그 때 내부에서 사용되고 있는 count값인 0이 저장이 되고 그 때의 렉시컬 환경이 콜백 함수에 전달이 된다.
그래서 0+1은 1이 되고 아무리 setCount를 호출해도 1이 되는 것이다!

그렇다면 한번 add버튼을 클릭했을 때 바로 5가 되려면 어떻게 해야할까?

이전 값을 전달하는 콜백 함수를 사용하면 된다!

  onClick={() => {
          setCount((prev) => prev + 1);
          setCount((prev) => prev + 1);
          setCount((prev) => prev + 1);
          setCount((prev) => prev + 1);
          setCount((prev) => prev + 1);
        }}

setCount가 호출될 때 이전 상태값을 prev라는 콜백 인자로 전달받는다!
따라서 최종 setCount가 5로 설정되는 것이다!

profile
프론트엔드 대장이 되어보쟈

0개의 댓글