State 상태
1. useState(기본값)
- setState는 전후비교로 리렌더링(업데이트) 되기때문에, state 원본을 훼손해서는 안된다!!
- 기본 예시
import React, { useState } from 'react';
function Counter(props) {
const [ count, setCount ] = useState(0);
return (
<div>
<button onClick={ () => (count = count + 1) }> +1 </button>
<button onClick={ () => setCount(count + 1) }> +1 </button>
<br />
Counter: { count }
</div>
);
}
export default Counter;
2. setState(원시타입)
- 원시타입: 불변성O. 변수에 원시타입의 값을 할당하면, 메모리에 값 자체가 저장된다.
- setState(업데이트 값)
- 기본 예시
import React, { useState } from 'react';
function Counter(props) {
const [ count, setCount ] = useState(0);
const [ show, setShow ] = useState(true);
const operators = [ "+", "-", "*" ];
const [ operator, setOperator ] = useState(operators[0]);
return (
<div>
<button onClick={
() => {
let result;
if (operator === "+") result = count + 1
if (operator === "-") result = count - 1
if (operator === "*") result = count * 1
setCount(result);
}
}>
{ operator } 1
</button>
<button onClick={ () => setShow(!show) }>Show and Hide</button>
<button onClick={
() => {
const idx = Math.floor(Math.random() * operators.length);
setOperator(operators[idx]);
}
}>
Change Operator
</button>
{ show && `Counter: ${count}` }
</div>
);
}
export default Counter;
3. setState(객체타입)
- 참조타입(객체타입): 불변성X. 변수에 참조타입의 값을 할당하면, 메모리값이 담긴 주소가 저장된다.
- state 원본을 훼손하지 않는 방법을 사용해야, 전후비교로 업데이트가 된다.
- 참조타입은 { ...obj }, [ ...arr ] 이런식으로 복사를 통해 해결해야한다.
- setState({ ...객체복사, 업데이트 값 })
- 기본 예시
import React, { useState } from 'react';
function Counter(props) {
const operators = ["+", "-", "*"];
const [ info, setInfo ] = useState({
count: 0,
show: true,
operator: operators[0]
});
return (
<div>
<button onClick={
() => {
let result;
if (info.operator === "+") result = info.count + 1
if (info.operator === "-") result = info.count - 1
if (info.operator === "*") result = info.count * 1
setInfo({ ...info, count: result });
}
}>
{ info.operator } 1
</button>
<button onClick={ () => setInfo({ ...info, show: !info.show }) }>Show and Hide</button>
<button onClick={
() => {
const idx = Math.floor(Math.random() * operators.length)
setInfo({ ...info, operator: operators[idx] });
}
}>
Change Operator
</button>
{ info.show && `Counter: ${info.count}` }
</div>
);
}
export default Counter;
4. setState()는 '비동기적'으로 실행된다
- 이 문제를 해결하려면, 호출할때 setState(() => {})
- 기본 예시
import React, { useState } from "react";
export default function App() {
const [ number, setNumber ] = useState(1);
const add = () => setNumber((number) => number + 1);
const sub = () => setNumber((number) => number - 1);
const mul2 = () => setNumber((number) => number * 2);
const mul2add1 = () => {
mul2();
add();
};
return (
<div>
<h1> Number : { number } </h1>
<div>
<button onClick={ add }> + 1 </button>
<button onClick={ sub }> - 1 </button>
<button onClick={ mul2 }> *2 </button>
<button onClick={ mul2add1 }> *2 + 1 </button>
</div>
</div>
);
}