리액트 - 컴포넌트 (2) state
목차
1. state
2.클래스형 컴포넌트 state
3.함수 컴포넌트 useState
state
리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미합니다. 리액트에는 두 가지 종류의 state가 있습니다. 하나는 클래스형 컴포넌트의 state, 다른 하나는 함수 컴포넌트에서 useState 함수를 통해 사용하는 state입니다.
클래스형 컴포넌트의 state
class Counter extends Component {
constructor(props) {
super(props);
//state의 초깃값 설정하기
this.state = {
number: 0
};
}
클래스형 컴포넌트 호출부입니다. super를 사용해서 Component 클래스의 생성자를 호출해줍시다.
render() {
const { number } = this.state //state를 조회할 때는 this.state로 조회합니다.
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
render 함수에서 현재 state를 조회할 때는 this.state를 조회하면 됩니다. 그리고 button 안에 onClick 이벤트를 넣어주었습니다. this.setState 를 통해서 state 값을 바꿀 수 있습니다.
버튼을 누를 때 마다 1씩 증가합니다.
state를 constructor에서 꺼내기
constructor 메서드를 선언하지 않고도 state 초깃값을 설정할 수 있습니다.
//after
class Counter extends Component {
state = {
number: 0,
fixNumber: 0
};
this.setState에 객체 대신 함수 인자 전달하기
아래 이벤트를 실행하면 number는 예상과 다르게 2가 증가하게 됩니다.
onClick={() => {
this.setState({ number : number + 1 }); // (1)
this.setState({number : this.state.number + 2}) // (2)
}}
useState는 비동기처리를 합니다. 일반적으로 비동기 논블락킹 환경에서는 작업의 순서에 구애받지 않고 I/O 가 일어나도 제어권을 넘기지 않고 결과를 기다리지 않은채 자신의 작업을 수행하는데요.
(1)의 결과를 기다리지 않고 (2)를 실행할 수 있다는 이야기 입니다. react에서는 가장 최근에 갱신된 값을 제공한다고 하네요. 이러한 예상치 못한 결과를 해결하기 위해서는 setState를 사용할 때 객체 대신에 함수를 인자로 넣어 줄 수 있습니다.
이렇게 인자로 함수를 받으면 원하는 결과를 도출할 수 있습니다.
onClick={() => {
this.setState(preState => ({
number: preState.number + 1
}));
this.setState(preState => ({
number: preState.number + 2
}));
}}
this.setState가 끝난 후 특정 작업 실행하기
setState() 는 두번째 인자로 callback을 받습니다.
onClick={() => {
this.setState(
{
number: number + 1
},
() => {
console.log('방금 setState가 호출되었습니다.');
console.log(this.state);
}
)
}}
함수 컴포넌트에서 useState
리액트 16.8 이후부터 useState라는 함수를 사용하여 함수 컴포넌트에서도 state를 사용할 수 있게 되었습니다. 이 과정에서 Hooks라는 것을 사용하게 됩니다. 포스팅에서는 useState만 배우고 이후 Hook에 대해 정리하도록 하겠습니다.
useState 사용하기
위 스펙에 따라서 만들어주면 된다. useState 함수의 인자로는 상태의 초기값을 입력해주면 되고 값의 형태는 자유이다. 문자열뿐만 아니라 숫자, 객체 등 제약을 받지 않는다.
배열이 반환되는데 첫 번째 원소(state)는 현재 상태입니다. 두번째 원소로는 상태를 바꿔주는 함수가 반환된다.
const Say = () => {
const [message, setMessage] = useState('버튼을 눌러주세요');
const onClickEnter = () => setMessage('안녕하세요');
const onClickLeave = () => setMessage('안녕히 가세요!');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1>{message}</h1>
</div>
)
};
아래처럼 한 컴포넌트에서 useState를 여러 번 사용할 수도 있습니다.
const Say = () => {
const [message, setMessage] = useState('버튼을 눌러주세요');
const onClickEnter = () => setMessage('안녕하세요');
const onClickLeave = () => setMessage('안녕히 가세요!');
const [color, setColor] = useState('black');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{color}}>{message}</h1>
<button style={{ color: 'red' }} onClick={() => setColor('red')}>
빨간색
</button>
<button style={{ color: 'green' }} onClick={() => setColor('green')}>
초록색
</button>
<button style={{ color: 'blue' }} onClick={() => setColor('blue')}>
파란색
</button>
</div>
)
};