useState는 React에서 상태를 관리하는데 매우 중요한 hook이다.
useState를 사용하면 컴포넌트의 상태를 추척, 관리할 수 있으며, 컴포넌트의 렌더링을 최적화하고 재사용성을 높일 수 있다.
아래의 내용은 공식문서 useState에 관한 내용을 정리한 글이다.
useState()
const [state, setState] = useState(initialState);
규칙
- 컴포넌트의 최상위 레벨에서 useState를 호출해야 한다.
- 주의! 반복문이나 조건문 안으로 호출 할 수 없음.
- 배열 구조 분해를 사용해 [someting, setSomething]과 같은 state 변수의 이름을 지정하는 것이 관계이다.
- 첫 번째 요소는 상태를 의미함. 첫 번째 렌더링 중에는 전달한
initialState
와 일치한다. - 두 번째 요소는 상태를 다른 값으로 업데이트하고 리렌더링을 트리거할 수 있는 set 함수이다.
- 첫 번째 요소는 상태를 의미함. 첫 번째 렌더링 중에는 전달한
이전 state 기반으로 state 업데이트 하는 법
import { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
const clickHandler = () => {
setCount(count +1)
setCount(count +1)
setCount(count +1)
};
return (
<>
<div>{count}</div>
<button onClick={clickHandler}>click</button>
</>
);
}
export default App;
- 3씩 증가하지 않는 이유는 set함수를 호출해도 이미 실행 중인 코드에서 count 상태가 업데이트 되지 않기 때문이다.
- React는 성능 향상을 위해서 setState 연속 호출 시 한번에 처리에 렌더링된다.
- 이는 배치 개념이다. 다음 글에서 일괄 처리에 대해 설명하겠다.
2023.07.14 - [개발언어/React] - [공식문서 톺아보기] batching / setState는 비동기인가요?
import { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
const clickHandler = () => {
setCount(prevCount => prevCount+1)
setCount(prevCount => prevCount+1)
setCount(prevCount => prevCount+1)
};
return (
<>
<div>{count}</div>
<button onClick={clickHandler}>click</button>
</>
);
}
export default App;
- 업데이트 함수(prevCount ⇒ prevCount+1)는 대기 중인 상태를 가져와서 다음 상태값을 계산한다.
- React는 업데이트 함수를 Queue에 넣는다.
- prevCount ⇒ prevCount+1
- 초기값인 상태값 0을 다음 상태값으로 1로 반환한다.
- prevCount ⇒ prevCount+1
- 대기 중인 상태값 1을 받아 다음 상태값으로 2를 반환한다.
- prevCount ⇒ prevCount+1
- 대기 중인 상태값 2을 받아 다음 상태값으로 3를 반환한다.
- 대기 중인 업데이트가 없으니, react는 현재 상태값 3을 저장한다.
초기 state 다시 생성하지 않기
const [count, setCount] = useState(getInitial());
const clickHandler = () => {
setCount(prevCount => prevCount + 1);
const [count, setCount] = useState(getInitial);
const clickHandler = () => {
setCount(prevCount => prevCount + 1);
- 초기 state에 함수를 호출하면, 모든 렌더링에서 함수를 호출하기 때문에 큰 배열이나, 값비싼 계산을 수행하는 경우 코드 효율성이 떨어진다.(동작은 눈에 띄는 차이가 없음)
- 함수 자체로 전달하여 초기 렌더링에만 사용하도록 하자!
이전 렌더링에서 얻은 정보 저장하기
- props가 변경될 때 state 변수를 변경하고 싶다면?
- 예로 들어, 카운터가 마지막 변경 이후 증가 또는 감소했는지 표시하고 싶다면? 이전 값을 추적하여 현재값과 비교하고 표시를 해야한다.
import { useState } from 'react';
import css from './App.css'
import CountLabel from './CountLabel';
function App() {
const [count, setCount] = useState(0);
const upClickHandler = () => {
setCount(prevCount => prevCount + 1);
};
const downClickHandler = () => {
setCount(prevCount => prevCount - 1);
};
return (
<div className='App'>
<div>{count}</div>
<button onClick={upClickHandler}>Increment</button>
<button onClick={downClickHandler}>Decrement</button>
<CountLabel count={count}/>
</div>
);
}
export default App;
// CountLabel.js
import { useState } from "react"
function CountLabel({count}) {
const [prevCount, setPrevCount] = useState(count)
const [trend, setTrend] = useState(null);
if (prevCount !== count) {
setPrevCount(count);
setTrend(count > prevCount ? 'increasing' : 'decreasing')
}
return(
<>
{trend && <div>The count is {trend}</div>}
</>
)
}
export default CountLabel
참고자료
https://react.dev/reference/react/useState
'개발언어 > React' 카테고리의 다른 글
[🚨응급실 알리미]React Query와 Router loader 함께 쓰기 (0) | 2023.09.28 |
---|---|
[🚨응급실 알리미] Recoil과 React-query를 선택한 이유 (2) | 2023.09.06 |
Virtual DOM이 뭔가요? (0) | 2023.07.21 |
useState를 바닐라JS로 구현하기 (0) | 2023.07.14 |
[공식문서 톺아보기] batching / setState는 비동기인가요? (2) | 2023.07.14 |
댓글