State-Prev

김하은·2023년 1월 28일
0

state는 리엑트 컴포넌트에서 사용하는 변수로,데이터를 담기위한 상자라고한다.
이 상자에 담긴 내용들은 함수가 다 끝난 뒤에 반영이 된다.

state를 다시 알아보기 위해couter올리는 부분으로 실습을 진행하였다.

import { useState } from 'react'

function New() {
const [count, setCount] = useState(0)

function handleClick() {
    setCount(count + 1)     // 갯수가 증가하면서, 화면에 정상적으로 **반영됨**
}

return (
    <div>
        <h1>{count}</h1>
        <button onClick={handleClick}>state를 사용하여 count 증가</button>
    </div>
)

}

export default New

코드를 실행해 버튼을 클릭하면 정상적으로 1씩 증가하는것을 볼 수 있었다.

그런데, 만약 5씩 증가하는 것을 보기위해

function handleClick() {
   setCount(count + 1)      // 현재 count는 0 + 1 => 1을 상자에 담는다.
   setCount(count + 1)      // 1 이 상자에 담겼지만 여전히 count는 0 이므로 1이 상자에 담긴다
   setCount(count + 1)      // ...
   setCount(count + 1)      // ...
   setCount(count + 1)      // 같은 방식으로 최종적으로 1이 상자에 담겨 화면에 1이 반영된다
}

이렇게 적어주면 어떤 결과가 나올까?
우리가 원하는 결과는 클릭시 한번에 5가 증가하는 것이다.
그런데, state는 앞서 말했듯이 해당 함수가끝날때까지 적용되지 않고 상자안에서 계속쌓이다가 함수가 끝나기 바로전에 적용되는 state값이 최종적으로 적용되어 마지막 값만으로 즉, 카운트가 하나가 증가한 값으로 적용된것이다.

의도한 5씩 증가하게 적용하려면
prev라는것을 사용해야한다.

function handleClick() {
   setCount((prev)=>prev+1)     
   setCount((prev)=>prev+1)    
   setCount((prev)=>prev+1)    
   setCount((prev)=>prev+1)     
   setCount((prev)=>prev+1)     
}

prev로 임시 저장공간. 즉, state를 임시로 저장해두었던 바로 그 상자에서 값을 그대로꺼내와 바로 적용하는 방법이다.

물론 초기에는 상자에 값이 없기때문에 초기에 지정해준 값을 꺼내온다.
초기값에 + 1 을 한값이 상자에 들어가고,
다시 상자에서 값을 꺼내온다. 그러면 0 + 1 에서 1이 들어가는 것, 이 1을 다시 꺼내와
1 + 1 해서 2가 들어가고,
2 + 1 해서 3이 들어가고 3을 다시 꺼내온다.
3 + 1 해서 4가 들어가고
이번엔 4를 꺼내와 + 1 을 하고 그렇게 최종적으로 5가 상자에 저장되고,
함수가 끝났으니, 결국 5가 적용되어 5씩 증가하는것을 볼 수 있다.

prev를 사용하면 코드 리펙토링시에도 많은 도음이 된다!!


++ 추가로..
readOnly 라는 속성은 boolean타입으로 data?.fetchBoard.writer 이라는 값을 넣으면 타입스크립트 오류가 나는데. 해당값이 string이기때문이다.
따라서 이 타입이 string타입이 되도록 이중부정연산자를 사용해줘야한다고 한다.

data?.fetchBoard.writer 는 string타입이지만 boolean타입으로 보면 string이 있는것이기에 true값이라고 본다. 그 앞에 !을 붙여서 !data?.fetchBoard.writer라고 하면 false가 되고,
우리가 적용했던 값을 그대로 가져오기 위해서는 여기에 한번 더 !를 붙인 이중부정연산자를 사용하면 true 상태 그대로 가져올 수 있다.

그런데 이렇게 적용하고 eslint와 타입스크립트를 연결한결과 빨간줄이 생긴것을 발견했다.
애초에 Boolean으로 감싸주면 빨간줄이 사라진다.
아직까지 약간 이해가 안가는데... 타입을 명시해줌으로써 해당값을 true로 인식하게 해주는 원리인가보다 하고 이해하고 넘어간다...

0개의 댓글