기존 React의 함수 컴포넌트에서는 state를 지정할 수 없었다.
→ 클래스 컴포넌트로 바꿔줘야했다.
hook을 사용하면 이제 함수 컴포넌트에서도 state를 지정할 수 있다!
(단, 클래스 컴포넌트에서는 hook이 동작하지 않는다)
import React, { useState } from 'react';
function Example() {
// 새로운 state 변수를 선언하고, 이것을 count라 부르겠습니다.
const [count, setCount] = useState(0);
클래스 컴포넌트로 표현하면?
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
<p>You clicked {count} times</p>
<p>You clicked {this.state.count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
function ExampleWithManyStates() {
// 여러 개의 state를 선언할 수 있습니다!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
class ExampleWithManyStates extends React.Component {
constructor(props) {
super(props);
this.state = {
age: 42,
fruit: 'banana'
todos: [{ text: 'Learn Hooks' }]
};
}
지역 변수를 개별적으로 갱신 가능
function handleOrangeClick() {
// this.setState({ fruit: 'orange' })와 같은 효과를 냅니다.
setFruit('orange');
}
여러 개의 state 변수를 사용하지 않아도 된다. state 변수는 객체와 배열을 잘 가지고 있을 수 있으므로 서로 연관있는 데이터를 묶을 수 있다.
하지만 클래스 컴포넌트의 this.setState와 달리 state를 갱신하는 것은 병합하는 것이 아니라 대체하는 것이다.
function Box() {
const [state, setState] = useState({ left: 0, top: 0, width: 100, height: 100 });
// ...
}
이런 식으로 하나의 state에 여러 값을 넣고 싶다면
setState(state => ({ ...state, left: e.pageX, top: e.pageY }));
"... state"를 써서 width와 height가 "손실"되지 않게해야 한다.
따라서, 그냥 함께변경 되는 값에 따라 state를 여러 state 변수로 분할하는 것을 추천!!
function Box() {
const [position, setPosition] = useState({ left: 0, top: 0 });
const [size, setSize] = useState({ width: 100, height: 100 });
useEffect(() => {
function handleWindowMouseMove(e) {
setPosition({ left: e.pageX, top: e.pageY });
}
// ...
예를 들어 컴포넌트 state를 position 및 size 객체로 분할하고 병합할 필요 없이 항상 position을 대체 할 수 있다.
모든 state를 단일 useState 호출에 넣고 필드마다 useState 호출을 두는 방법도 쓸 수 있다.