변수는 변경되어도 자동으로 화면이 바뀌지 않지만 state를 사용하면 자동으로 화면이 바뀐다.
import react, {useState} from 'react';
const [state, setState] = useState(초기값, 생략가능)
state는 현재 상태 값, setState는 state를 업데이트 하는 함수를 의미한다.
const로 선언하는 이유
- 변수의 재할당을 막기 위해서. useState를 사용한 변수 변경만을 허락하기 위해서 const로 선언한다.
import { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const plus = () => {
setCount(count + 1);
console.log(count); // setCount로 count를 변경한 후 바로 콘솔에 찍었다
}
const minus = () => {
setCount(count - 1);
console.log(count); // setCount로 count를 변경한 후 바로 콘솔에 찍었다
}
return (
<div className='container'>
<h2 className='int'>{ count }</h2>
<button className='plus' onClick={plus}>+</button>
<button className='minus' onClick={minus}>-</button>
</div>
)
}
export default Counter;
console.log의 결과값을 보면 값이 바로 바뀌지 않는다.
setCount는 현재 state의 값에 대한 변화를 요청하기만 하는 것이라서 리액트가 상태를 바꾸고 화면을 다시 그리기를 기다려야 한다.
리액트는 이벤트 핸들러가 닫히는 시점에 setState를 종합하여 한번에 처리한다.
state는 값이 변경되면 리렌더링이 발생하는데 state가 많을수록 리렌더링이 계속 일어나 속도가 저하되는 등 성능적으로 문제가 많아지게 된다
그래서 16ms 동안 변경된 상태 값들을 모아서 한번에 리렌더링을 진행하는데 이를 batch update라 한다
const plus = () => {
setCount(count + 1);
console.log(count);
setCount(count + 2);
console.log(count);
setCount(count + 3);
console.log(count);
}
1+2+3 =6씩 증가하는게 아닌 마지막 setCount의 결과인 3씩 증가하게 된다.
const plus = () => {
setCount(count => count + 1);
setCount(count => count + 2);
setCount(count => count + 3);
}
setCount(count+1)에서 count는 렌더링 시작 시점의 count이기 때문에 최근에 바뀌었어도 반영되지 않는다. 위처럼 콜백 함수를 사용하면 항상 최신의 값을 인자로 받아와서 처리하기 때문에 최신 값을 받아서 처리할 수 있다.
// App.js
import './App.css';
import Counter from './counter';
function App() {
return (
<div>
<Counter/>
</div>
);
}
export default App;
//Counter.js
import react,{useState} from 'react'
const Counter = ()=>{
const [count, setCount] = useState(0);
const onIncrease = () =>{
setCount(count +1);
}
const onDecrease = ()=>{
setCount(count -1);
}
return(
<div>
<h2>{count}</h2>
<button onClick={onIncrease}>+</button>
<button onClick={onDecrease}>-</button>
</div>
)
}
export default Counter;