컴포넌트 선언 방식에는 2가지 방식이 있다.
함수형 컴포넌트와 클래스형 컴포넌트
각각의 장단점을 확인해보자
state를 선언하는 방식에도 차이가 있다
컴포넌트에 state를 설정할 때는 constructor에 메서드를 작성하여 설정한다.
이는 컴포넌트의 생성자 메서드이고, 클래스형 컴포넌트에서 constructor를 작성할 때는 반드시 super(props)를 호출해줘야됌. 이 함수가 호출되면 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 주기 때문
또한 컴포넌트의 state는 객체 형식이어야된다.
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
// state의 초깃값 설정하기
this.state = {
number: 0,
fixedNumber: 0,
};
}
render() {
const { number, fixedNumber } = this.state; // state조회는 this.state로 가능
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정
onClick={() => {
// this.state를 사용하여 state에 새로운 값을 넣을 수 있음
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
이 방법을 사용하면 constructor 메서드를 선언하지 않고 state의 초깃값 설정 가능하다.
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state; // state조회는 this.state로 가능
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정
onClick={() => {
// this.state를 사용하여 state에 새로운 값을 넣을 수 있음
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
import React, { useState } from 'react';
function Counter() {
const [number, setNumber] = useState(0);
const onIncrease = () => {
setNumber(number + 1);
}
const onDecrease = () => {
setNumber(number - 1);
}
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
함수형 컴포넌트에서의 useState 초깃값은 클래스형 컴포넌트와 다르게 객체가 아니어도 상관없다.
값의 형태는 자유
state를 사용할 때 주의 사항
클래스형 컴포넌트든 함수형 컴포넌트든 state를 사용할 때 주의해야 할 사항이 있다.
state값을 바꿀때는 setState 혹은 useState를 통해 전달받은 세터 함수를 이용해야한다.
리액트에서 직접적으로 상태를 변경하는건 리액트 규칙에 위반되기 때문이다.
props와 state의 차이점
props와 state는 둘 다 컴포넌트에서 사용하거나 렌더링할 데이터를 담고 있으나 그 역할은 매우 다르다.
props는 부모 컴포넌트가 설정하고, state는 컴포넌트 자체적으로 지닌 값으로 컴포넌트 내부에서 값을 업데이트 할 수 있기 때문.
props를 사용한다고 해서 값이 무조건 고정적이지는 않다. 부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하고, 자식 컴포넌트에서 특정 이벤트가 발생할 때 부모 컴포넌트의 메서드를 호출하면 props도 유동적으로 사용할 수 있기 때문이다.
정리
리액트 공식 문서에서는 가능하면 함수형 컴포넌트와 React Hooks를 사용할 것을 권장하고있다. 따라서 함수형 컴포넌트와 함께 useState를 사용하자!