아래와 같은 코드에서 버튼을 눌렀을 때 숫자가 증가하고 화면에 표시되는 것을 기대할 것이다.
import React from 'react';
function Counter(props) {
let num = 0;
const incrementNum = () => {
num += 1
console.log(num);
};
return (
<div>
<p>The Count is : {num}</p>
<button onClick={incrementNum}>Increment</button>
</div>
);
}
export default Counter;
하지만 console에서는 늘어나지만 DOM에서 component가 업데이트 되지 않는다.
이는 리액트가 컴포넌트를 렌더링하는 방식, 그리고 언제 다시 렌더링하는지와 관련이 있다.
State는 컴포넌트의 모든 인스턴스에 특화된 데이터이고 바뀔 수 있다.
컴포넌트 안에서 바꾸고자 하는 데이터가 있으면 State를 포함해야 할 수 있다.
react에는 10개에서 15개의 훅이 있는데 훅이라는 함수는 기본적으로 리액트를 통해 자체 컴포넌트에 통합하여 기능을 추가하도록 선택할 수 있는 함수다.
useState는 단일한 상대 조각, 단일한 상대 변수를 설정하는데 원하는 대로 선택 할 수 있다.
const [count, setCount] = useState(0);
괄호에 들어가는 값은 초기값이 된다.
useState()는 배열을 반환한다. 그 배열에는 정확히 두개의 요소가 포함되어 있다.
첫번째 요소는 상태 그 자체이다. 즉, 상태 변수
이고
두번째 요소는 상태를 변경하는 데 사용하는 함수
이다.
useState는 리액트 컴포넌트 안에 존재해야 한다.
함수를 호출해서 상태 변수를 변경할 때마다 컴포넌트가 재렌더링된다.
완성 코드
import React from 'react';
import { useState } from 'react';
function Counter(props) {
const [num, setNum] = useState(5);
const changeNum = () => {
setNum(num+1);
};
return (
<div>
<p>The Count is : {num}</p>
<button onClick={changeNum}>Increment</button>
</div>
);
}
export default Counter;
이와 같이 제대로 적용이 되는 것을 확인할 수 있다.
import React from 'react';
import "./Toggler.css"
import { useState } from 'react';
function Toggler(props) {
const [isHappy, setIsHappy] = useState(true);
const toggleIsHappy = () => setIsHappy(!isHappy);
return (
<p className='Toggler' onClick={toggleIsHappy}>
{isHappy ? "😄" : "😭"}
</p>
);
}
export default Toggler;
같은 컴포넌트에서 2개의 useState를 사용하고 있지만 서로 완전히 분리되어 있다.
import React from 'react';
import "./Toggler.css"
import { useState } from 'react';
function TogglerCounter(props) {
const [isHappy, setIsHappy] = useState(true);
const [count, setCount] = useState(0);
const toggleIsHappy = () => setIsHappy(!isHappy);
const incrementCount = () => setCount(count + 2);
return (
<div>
<p className='Toggler' onClick={toggleIsHappy}>
{isHappy ? "😄" : "😭"}
</p>
<p>{count}</p>
<button onClick={incrementCount}>+</button>
</div>
);
}
export default TogglerCounter;
ColorBoxGrid.jsx
import React from 'react';
import ColorBox from './ColorBox';
import './ColorBoxGrid.css';
function ColorBoxGrid({colors}) {
const boxes = [];
for(let i =0; i<25; i++){
boxes.push(<ColorBox colors={colors}/>);
}
return (
<div className='ColorBoxGrid'>
{boxes}
</div>
);
}
export default ColorBoxGrid;
ColorBox.jsx
import React from 'react';
import './ColorBox.css'
import { useState } from 'react';
function randomChoice(arr){
const idx = Math.floor(Math.random() * arr.length);
return arr[idx];
}
function ColorBox({colors}) {
const [color, setColor] = useState(randomChoice(colors));
const changeColor = () => {
const randomColor = randomChoice(colors);
setColor(randomColor);
}
return (
<div onClick={changeColor} className='colorBox' style={{backgroundColor : color}}>
</div>
);
}
export default ColorBox;
다음과 같은 결과가 나온다.