useState의 setState에 함수 넣기 (Functional Update)

2023. 8. 17. 01:42·Frontend/React

useState Hook 개념

useState는 상태 변경이 일어나는 변수를 쉽고 편하게 관리하기 위한 React Hook이다.

useState는 원래 아래와 같은 배열을 반환한다.

[변수의 값, 변수를 변경(=set)하는 함수 이름]

 

배열을 반환하므로 각 인덱스를 직접 찍어보는 것도 가능하다.

const stateArray = useState()
console.log(stateArray[0])	// undefined
console.log(stateArray[1])	// function

 

 

여기서 상태 변수에 초기값을 할당하고 싶으면 useState 함수 인자로 초기값을 입력하면 된다.

const stateArray = useState("Hi Hello")
console.log(stateArray[0])	// "Hi Hello"
console.log(stateArray[1])	// function

 

인덱스를 직접 찍는 것보다 아래와 같이 배열을 구조 분해하여 할당하면 더 편하게 사용 가능하다. 가장 보편적이고 정석적인 사용 방법이다.

(아래 코드는 이 위 코드와 같은 기능을 한다)

const [state, setState] = useState("Hi Hello")
console.log(state)		// "Hi Hello"
console.log(setState)	// function

 


setState로 상태 업데이트하기 (1)

쉬운 예제로 counter를 만든다고 해보자. 사용자가 버튼을 클릭했을 때 state에 1을 더해주는 것이다. 그럼 아래와 같이 짤 수 있다.

const [state, setState] = useState(0)
const onClick = () => {
  setState(state + 1)
}

 

그런데 개발하다보면 state 변경이 제대로 이루어지지 않는 상황을 마주하게 된다. 아 스쳐지나가는 옛 기억..

예를 들어, 똑같이 counter를 만드는데 버튼이 두 개라고 해보자. 버튼 A는 방금 위에서 했던 것처럼 눌리면 바로 1을 더해주는 거고, 버튼 B는 클릭된 시점에서 3초 이후에 1을 더하는 버튼이다.

const [state, setState] = useState(0)

const onClickA = () => {
  setState(state + 1)
}

const onClickB = () => {
  // 대충 setTimeout 써서 3초 기다리는 코드
  setState(state + 1)
}

 

버튼 B를 누르고 기다리는 3초 동안에 버튼 A를 마구 누르면 state는 어떻게 될까? 'B를 누른 횟수 1회 + A를 누른 횟수 n회'가 되면 이상적일 것이다. 그러나 실제로는 1이 된다. 왜냐하면 onClickB 함수 내 state 변수는 함수가 호출된 시점의 state, 즉 0이기 때문이다. 버튼 A를 아무리 눌러도 B를 눌렀을 시점에 state의 값은 0이고, 3초 후에 state + 1 이 일어나므로 1이 되는 것이다.

 

 

이런 경우도 마찬가지이다.

const [state, setState] = useState(0)
const onClick = () => {
  setState(state + 1)	// 0 + 1
  setState(state + 1)	// 0 + 1
  setState(state + 1)	// 0 + 1
}

하나의 함수 내에서 "setState(state + 1)"를 여러 번 반복하고 있지만, state 값은 1이다. 이유는 위와 같다(호출 시점에 state가 0).

 

 

setState로 상태 업데이트하기 (2): Functional Update

setState에 함수를 넣으면 앞서 겪은 상황들을 해결할 수 있다. state + 1과 같이 상수가 아니라 함수를 넣어 업데이트 해주는 것이다.

const [state, setState] = useState(0)
const onClick = () => {
  setState((currentState) => currentState + 1)	// 0 + 1
  setState((currentState) => currentState + 1)	// 1 + 1
  setState((currentState) => currentState + 1)	// 2 + 1
}

setState에 집어넣은 함수의 인자 currentState는 자동으로 현재 state 값을 추적, 맵핑한다(이름이 currentState가 아니어도 됨).

즉 함수로 업데이트할 경우, 항상 최신값을 보장할 수 있다.

 

참고로 setState 함수는 원래 이렇게 생겼다.

setState(updater[, callback])

마무리

  • React의 useState는 [상태 변수 값, 상태 변수를 변경할 함수]를 반환한다.
  • setState 함수 인자로 state 값을 직접 넣는 경우, 호출 시점의 state 값이 사용된다.
  • setState 함수 인자로 함수를 넣는 경우, 현재 state 값을 자동 맵핑하며 즉각 반영한다.
  • setState()가 컴포넌트를 항상 즉각적으로 갱신하는 명령이 아니다. '갱신 요청'으로 생각하면 편하다. setState()를 사용해도 다른 변경 사항들과 한꺼번에 갱신하기 위해 갱신 타이밍이 뒤로 미뤄질 수 있다는 걸 주의하자.

 

참고 자료

  • https://ko.legacy.reactjs.org/docs/react-component.html#setstate
  • https://developer-talk.tistory.com/252
저작자표시 비영리 변경금지 (새창열림)

'Frontend > React' 카테고리의 다른 글

리액트의 이벤트 처리 방식 까보기  (0) 2025.03.11
[react] 달력 만들기 01  (0) 2023.01.31
[HOC] about HOC(Higher Order Component)  (0) 2022.09.13
[Redux Tutorial] Login page 만들며 Redux 이해하기  (0) 2022.09.13
[Redux Tutorial] about Redux  (0) 2022.09.13
'Frontend/React' 카테고리의 다른 글
  • 리액트의 이벤트 처리 방식 까보기
  • [react] 달력 만들기 01
  • [HOC] about HOC(Higher Order Component)
  • [Redux Tutorial] Login page 만들며 Redux 이해하기
톱치
톱치
나를 위한 기록을 합니다
  • 톱치
    기록
    톱치
  • 전체
    오늘
    어제
  • 블로그 메뉴

    • 홈
    • 방명록
    • 글쓰기
    • 전체보기 (51)
      • Articles (0)
      • Frontend (3)
        • JS, TS (16)
        • HTML, CSS (5)
        • React (6)
        • Dart (3)
      • Backend (6)
      • Others (3)
      • Algorithm (5)
      • 회고 (4)
  • 링크

    • GitHub
  • 태그

    login
    css
    javascript
    token
    TypeScript
    todolist
    프리코스
    js
    BCrypt
    BFS
    ts
    node.js
    dart
    programmers
    object
    React
    Redux
    Node
    회고
    우아한테크코스
  • hELLO· Designed By정상우.v4.10.3
톱치
useState의 setState에 함수 넣기 (Functional Update)
상단으로

티스토리툴바