useState 와 useEffect 발표 중 먼저 리액트의 대표적인 hook 중 하나인 useState 에 대해 알아보겠습니다! 😀
먼저 State 란❓
State는 한 컴포넌트 안에서 유동적인 데이터를 다룰 때 사용되며, 컴포넌트 안에서 데이터를 변경할 수 있습니다. 즉, State는 한 컴포넌트의 상태(State)를 나타냅니다.
- State는 컴포넌트 내에서 지속적으로 변경이 일어나는 값을 관리하기 위해 사용 합니다.
React Hooks 가 나오기 이전에는 상태값을 관리하기 위해 class 기반의 클래스 컴포넌트 를 작성해야했습니다. class 안에서 this.state 를 써주는 코드를 길게 작성해야 했습니다.
이렇듯, 클래스 컴포넌트는 간단한 상태 관리 조차도
함수형 컴포넌트에 비해 복잡하여 유지 보수가 힘들었습니다.
하지만, 리액트 16.8 버전부터 Hooks 라는 기능이 도입되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 됐습니다. Hooks 중에 useState() 함수가 있는데, 이를 통해 함수형 컴포넌트에서도 상태를 관리 할 수 있습니다.
그렇다면 useState 는❓
위에서 설명한 state 를 다룰 때 사용 합니다.
useState 의 모습은 아래와 같습니다
State 특징
- useState를 사용하여 할당받은 변수는 불변성 을 가집니다.
- 따라서 해당 값은 직접 수정이 불가능하며 해당 값을 변경하기 위해서는 반드시 Set 함수를 사용 해야 합니다.
- setState()가 쓰일 때, 컴포넌트의 state 객체에 대한 업데이트를 실행합니다. state가 변경되면, 컴포넌트는 리렌더링 됩니다.
state 값을 직접 변경하지 않고 setState 를 사용해야 할까❓
직접 state 를 수정하게 되면, 컴포넌트가 변경한 값을 인지하지 못하여 변경된 부분이 있다고 하더라도, 다시 리렌더링을 하지 않습니다.
특징 중 불변성을 기억하자❓
여기서 불변성은 메모리 영역에서의 직접적인 변경을 하지 않고, 기존의 값을 수정하지 않으며 새로운 값을 만들어 내는 것을 의미 합니다.
간단하게 요약만 하면 리액트 상태 업데이트 원리 때문 입니다.
state 의 불변성을 지켜줘야 리액트 컴포넌트에서 '상태가 업데이트 되었다.' 를 감지 할 수 있고 그에 따른 리렌더링이 진행 될 수 있습니다!
이를 위해 리액트는 얕은 비교를 합니다. 얕은 비교를 하면서 얻는 이점은
1. 효율적인 상태 업데이트
➡️ 객체의 프로퍼티(속성)를 하나하나 다 비교하지 않고, 객체의 참조 주소값만 변경되었는지 확인합니다.
➡️ 계산 리소스를 줄여주기 때문에 리액트는 효율적으로 상태를 업데이트 할 수 있습니다.
2. 사이드 이펙트 방지
➡️ 원시타입은 애시당초 불변성 특징을 가지고 있지만 참조타입인 객체나 배열의 경우 값을 변경할 때 원본데이터가 변경될 여지가 있습니다. ( 불변성이 지켜지지 않는다는 것! )
➡️ 이렇게 원본 데이터가 변경될 경우, 이 원본데이터를 참조하고 있는 다른 객체에서 예상치 못한 오류가 발생할 수 있습니다.
✅ 불변성에 대한 자세한 내용은 불변성 참고 하실 수 있습니다👨🏻💻
useState 예시
- count 라는 state 값을 만들고 초기 값으로 0 을 할당 했습니다.
- 숫자를 1씩 증감 하는 함수를 만들고
- 각 버튼을 누르면 숫자가 1씩 늘어나고 줄어드는 것을 확인 할 수 있습니다.
그렇다면 이런 코드는 어떻게 동작 할까요❓
코드만 보고 생각을 해보면 버튼을 클릭 할 때마다 +-4 범주로 동작 한다고 생각 할 수 있습니다.
하지만, 결과는 처음 봤던 예시랑 다르지 않습니다.
이유는, setState 는 비동기 함수 입니다.
비동기적으로 동작하는 이유는 일정시간 동안 변화하는 상태를 모아서 한 번에 렌더링 하기 위함 입니다.
하나의 컴포넌트 내에는 수 많은 상태가 존재 할 수 있습니다.
만약 상태 하나하나 바뀔 때 마다 화면을 리렌더링 하게 된다면 ??
➡️ 예상치 못한 사이드이펙트가 발생 할 수 있습니다.
이러한 특징을 batch 라고 합니다.
리액트는 batch 업데이트를 16ms 단위로 진행 합니다.
즉, 16ms 동안 변경된 상태 값들을 모아서 단 한 번만 리렌더링을 합니다.
➡️ 이러한 행동은 페이지의 렌더링 횟수를 줄여 조금 더 빠른 속도로 동작하게 해줍니다. 👍
➡️ setState() 호출되면, 바로 전달받은 state 값을 바꾸지 않고 이전의 virtual DOM 과 전달받은 state 가 적용된 virtual DOM 트리를 비교하는 과정을 거치고, 최종적으로 변경된 부분만 DOM에 적용 됩니다.
그렇다면 연속적으로 호출 할 수 있는 방법은❓
setState 의 인자로 이전 값을 기억 할 수 있는 함수를 전달 합니다!
정리
✅ State
- 리액트의 컴포넌트의 변경 가능한 데이터
- 컴포넌트를 개발하는 개발자가 직접 정의하여 사용
- state 의 값이 변경 될 경우 컴포넌트가 재렌더링됨
- 렌더링이나 데이터 흐름에 사용되는 값만 state에 포함시켜야 함
✅ State 의 특징
- 직접적인 변경이 불가능 함
- 클래스 컴포넌트 ( 많이 사용되지 않고 있음 )
- 생성자에서 모든 state를 한 번에 정의
- state 를 변경하고자 할 때에는 꼭 setState() 함수를 사용해야 함
- 함수 컴포넌트 ( 가장 많이 사용 중 )
- useState() 훅을 사용하여 각각의 state를 정의
- 각 state별로 주어지는 set함수를 사용하여 state 값을 변경
참고
https://www.delftstack.com/howto/react/react-setstate-prevstate/
https://ko.reactjs.org/docs/faq-state.html
http://www.yes24.com/Product/Goods/109781552
https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%EB%A6%AC%EC%95%A1%ED%8A%B8
'✅ Logs > Study' 카테고리의 다른 글
[React] - useContext (0) | 2023.02.11 |
---|---|
[React] - useEffect (0) | 2023.02.06 |
'SSR' vs 'CSR' 그리고 'MPA' vs 'SPA' (0) | 2023.02.01 |
[React] - React 의 불변성 (0) | 2023.01.17 |
[React] - 컴포넌트(Component)란? (0) | 2022.11.25 |