[React] useState

Seokkitdo·2022년 1월 15일
0

React

목록 보기
2/9
post-thumbnail

상태(state)

리액트의 컴포넌트에서는 동적인 값을 상태(state)라고 부릅니다. 리액트에서는 리렌더링을 위한 조건으로 여러 가지가 있는데 그 중 하나가 상태값 변경입니다. 리액트에서는 useState라는 훅을 통해 컴포넌트에서 상태를 관리할 수 있습니다.

function App() {
  const [count, setCount] = useState(0)
  const clickAddHandler = () => {
    setCount(prev => prev+1);
  }

  const clickSubHandler = () => {
    setCount(prev => prev-1)
  }
  return (
    <div className="App">
      <button onClick={clickAddHandler}>+</button>
      <button onClick={clickSubHandler}>-</button>
      <p>{count}</p>
    </div>
  );
}

const [count, setCount] = useState(0)
useState를 사용할 때에는 상태의 기본값을 파라미터로 넣어서 호출해줍니다. 이 함수를 호출해주면 배열이 반환이 되며 여기서 첫 번째 원소에는 현재 상태가 저장이 되며 두 번째 원소는 상태값을 바꿔주는 Setter 함수입니다.

 const [count, setCount] = useState(0)
 // 위의 코드는 아래와 같습니다.
 const countState = useState(0);
 const count = countState[0];
 const setCount = countState[1];

구조분해할당을 통해 각 원소를 뽑아서 더 간편하게 만들었습니다.

다시 정리해보면 state에는 현재 상태가 들어가 있으며 setState를 통해 상태를 변경할 수 있습니다.

위의 예시 코드를 보면 setCount(prev => prev+1) 부분에서 기존 상태값을 업데이트 하고 싶을 경우에는 그 다음 상태를 값으로 넘겨주는 것이 아닌 기존의 값을 업데이트 하는 함수를 넣어줄 수도 있습니다. 이를 함수형 업데이트라고 합니다.

setCount(count+1)
setCount(prev => prev+1)

그렇다면 기존 state에 연산을 하는 것과 함수형 업데이트를 하는 것에는 어떤 차이가 있을까요?
그 차이는 state를 변화시키는 동작에 있습니다.
함수형 컴포넌트에서 useState 훅을 사용하건 클래스형 컴포넌트에서 setState를 사용하건 state를 변화시키는 동작은 비동기적으로 이루어집니다.

this.state.value = 3;
this.setState({value: this.state.value + 1 });
this.setState({value: this.state.value + 1 });
this.setState({value: this.state.value + 1 });

// expected 6
// but this.state.value = 4

위의 코드는 6이 나올 것 같지만 4가 나오고 있습니다. 그 이유는 리액트가 여러 번 setState를 만나게 될 경우 일괄처리하여 state를 업데이트하기 때문입니다. 매번 호출 순서대로 바로 업데이트 하지 않고 인자로 전달된 객체들을 하나로 합치는 작업을 하게 되는데 이 과정을 '오브젝트 컴포지션' 이라고 합니다.

코드로 풀면 다음과 같다고 합니다.

const singleObj = Object.assign(
  {},
  objectFromSetState1,
  objectFromSetState2,
  objectFromSetState3
  );

만약 객체가 동일한 키를 가지고 있다면 가장 마지막에 전달된 객체의 키 값이 덮어씌워지기 때문에 6이 아닌 4가 나오게 된 것입니다.
쉽게 풀어보면 다음과 같습니다.

const mine = {beer: "cas"};
const yours = {beer: "max"};

const one = Object.assign({}, mine, yours);
one.beer === "max"; //true
console.log(one); //{beer: "max"}

이처럼 setState 역시 상태를 비동기적으로 갱신하기 때문에 제대로 코드를 작성한 것처럼 보여도 원하는데로 업데이트가 이루어지지 않는 경우가 가끔 생길 때도 있습니다.
바로 이 문제를 해결하기 위해 필요한 것이 함수형 업데이트인데, 그 이유는 객체가 아닌 함수를 setState가 호출하게 되면 병합할 객체가 없기 때문에 호출된 순서대로 큐에 넣게 되며 순서가 보장되어 호출하게 됩니다.


참고자료
https://dodokim.medium.com

profile
어제보다 성장해 나가고 싶은 개발자

0개의 댓글