일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 가상화
- 웹
- 쿠버네티스
- react
- 자바스크립트
- 솔리디티
- 프론트엔드
- 클라우드
- 파이썬
- k8s
- AWS
- docker
- 알고리즘
- CSS
- 블록체인
- 타입스크립트
- 리액트
- JavaScript
- TypeScript
- 이슈
- 컴퓨터공학
- es6
- HTML
- kubernetes
- next.js
- node.js
- 이더리움
- 백준
- BFS
- 백엔드
- Today
- Total
즐겁게, 코드
useState 훅에 대하여 본문
리액트로 컴포넌트를 만들때 함수 컴포넌트를 사용하는 것이 대세가 된 지금 함수 컴포넌트에서 클래스 컴포넌트의 동작을 구현하는 훅(Hook)에 대한 이해는 필수적이다.
오늘은 리액트 훅의 기본적인 특징과 클래스 컴포넌트의 상태를 구현하는 useState
훅에 대해 알아보자.
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
function decrementCount() {
// count 가 들어간 부분을 재렌더링함.
setCount((prevCnt) => prevCnt - 1);
}
function incrementCount() {
// count 가 들어간 부분을 재렌더링함.
setCount((prevCnt) => prevCnt + 1);
}
return (
<>
<button onClick={decrementCount}>-</button>
<span>{count}</span>
<button onClick={incrementCount}>+</button>
</>
);
}
export default App;
위는 클래스 컴포넌트의 상태와 setState
함수를 useState
훅으로 구현한 예제로 이렇게 훅을 사용하면 함수 컴포넌트에서 클래스 컴포넌트의 기능을 구현할 수 있다.
훅의 기본적인 특징으로는 클래스 컴포넌트의 동작을 함수 컴포넌트에 구현하는 것이 목적이므로 당연히 함수 컴포넌트에서만 사용이 가능하며 언제나 동일한 순서로 동작해야만 한다.
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
if (count > 10) {
const [bonus, setBonus] = useState(true);
}
function incrementCount() {
setCount((prevCnt) => prevCnt + 1);
}
return (
<>
<span>{count}</span>
<button onClick={incrementCount}>+</button>
</>
);
}
export default App;</pre
[위 코드는 에러를 출력합니다.]
따라서 이렇게 분기나 조건 내에 훅을 새롭게 정의하여 사용하는 것은 불가능하며, 위 코드는 카운터를 조작해 10점을 달성하면 bonus
라는 상태를 새로 생성하는 것처럼 보일 수도 있으나 실제로는 오류가 동작해 실행조차 불가능하다.
다양한 훅 중에서 처음 만나볼 리액트 훅은 useState
으로, useState
는 클래스 컴포넌트에서 사용하는 상태와 setState
를 대체하는 쉬운 훅임에도 불구하고 종종 사용법을 헷갈릴 때가 있다.
[useState 훅의 기본 형태]
import React, { useState } from "react"
// 배열의 분해 할당 문법을 기억하자.
const [state, setState] = useState(0)
useState
는 인자로 받은 값을 상태의 초깃값으로 삼고 언제나 초기 상태값과 업데이트 함수가 담긴 배열을 리턴한다.
즉 위의 코드에서는 state
라는 변수에 초기 상태값 0을 저장하며 setState
함수를 통해 state
변수에 담긴 상태값을 변경할 수 있게 되는데, 이걸 이해하려면 리액트의 특성을 이해해야 한다.
리액트의 강점 중 하나는 상태값이 변경되면 가상 돔을 활용해 해당 상태값이 사용된 부분만을 다시 렌더링한다는 것이다.
그러나 업데이트 함수가 아닌 사용자가 임의로 상태값을 변경하면 리액트는 변경사항을 인식하지 못하고 재렌더링(re-render)을 수행하지 않아 화면의 값이 갱신되지 않는데, 따라서 상태값을 변경할 때는 반드시 업데이트 함수를 사용해야만 한다.
이번에는 수수께끼를 한번 풀어보자.
import React, { useState } from "react"
function App() {
const [count, setCount] = useState(0)
function incrementCount() {
setCount(count + 1)
setCount(count + 1)
}
return (
<>
<span>{count}</span>
<button onClick={incrementCount}>+</button>
</>
)
}
export default App
이렇게 카운터 코드가 있을 때 + 버튼을 누르면 count 상태값은 2씩 증가할까?
물론 이런 문제가 으레 그렇듯 답은 "No" 다.
리액트는 불필요한 재렌더링을 최대한 줄이기 위해 여러 개의 업데이트 함수를 한번에 처리하는데, 이 때 동일한 업데이트 함수가 존재할 때는 나중에 사용된 업데이트 함수의 인자로 상태를 변경한다.
만약 부득이하게 한 블럭 안에서 업데이트 함수가 여러 번 작동해야 한다면 다음과 같이 인자에 함수를 넣어줄 수도 있는데 이렇게 인자로 주어진 함수의 인자는 언제나 직전 상태값이 되어 버튼을 누르면 의도한 대로 2씩 숫자가 증가하게 된다.
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
function incrementCount() {
setCount((count) => count + 1);
setCount((count) => count + 1);
}
return (
<>
<span>{count}</span>
<button onClick={incrementCount}>+</button>
</>
);
}
export default App;
아마 이 부분이 useState
를 사용할 때 가장 헷갈리는 부분일 텐데 업데이트 함수가 일괄적으로 상태를 업데이트하는 과정은 두 글을 읽어 보시는 것을 권해드립니다. (글 1) (글 2)
'🎨 프론트엔드 > React.js' 카테고리의 다른 글
useContext 훅에 대하여 (0) | 2021.01.05 |
---|---|
useRef 훅에 대하여 (1) | 2021.01.01 |
useMemo 훅에 대하여 (0) | 2020.12.30 |
Portal 사용하기 (0) | 2020.12.28 |
useEffect 훅에 대하여 (1) | 2020.12.28 |