React 17버전이 나온 기념으로 오랜만에 블로그 React 카테고리에 글을 남겨봅니다. 기존 Class 컴포넌트 강좌 이후 유튜브로만 강좌를 남겼는데 블로그 방문자가 많아져서 블로그에도 글을 쓰게 되었습니다.
useState
기존에는 state를 class 컴포넌트에서만 사용할 수 있었습니다. 함수 컴포넌트는 상태가 없는 컴포넌트라고도 불리웠죠. 이게 hooks들이 나오면서 완전 달라졌습니다. class 컴포넌트만 할 수 있었던 기능들이 모두 hooks로 들어오면서 오히려 class 컴포넌트를 사용할 필요가 없는 지경에 이르렀습니다.
이제부터 대표적인 hooks들을 알아보겠습니다. 첫 타자는 useState입니다. state를 추가해주는 hook이고 state는 화면과 관련된 데이터(변경되는)를 다룰 때 쓰시면 됩니다.
아래는 class 컴포넌트입니다. 이것을 함수 컴포넌트와 hooks로 바꿔보겠습니다.
import React, { Component } from 'react';
import PropTypes from 'prop-types'; // 패키지 추가
class Basic extends Component {
constructor(props) {
super(props);
this.state = {
hidden: false,
};
}
render() {
return (
<div>
<span>저는 {this.props.lang} 전문 {this.props.name}입니다!</span>
{!this.state.hidden && <span>{this.props.birth}년에 태어났습니다.</span>}
<button onClick={() => this.setState(() => ({ hidden: true }))}>숨기기</button>
</div>
);
}
}
Basic.propTypes = {
name: PropTypes.string.isRequired,
birth: PropTypes.number.isRequired,
lang: PropTypes.string,
};
Basic.defaultProps = {
lang: 'Javascript',
};
export default Basic;
다음과 같이 바꿀 수 있습니다.
import React, { useState } from 'react';
import PropTypes from 'prop-types'; // 패키지 추가
const Basic = ({ name, birth, lang }) => {
const [hidden, setHidden] = useState(false);
return (
<div>
<span>저는 {lang} 전문 {name}입니다!</span>
{!hidden && <span>{birth}년에 태어났습니다.</span>}
<button onClick={() => setHidden(true)}>숨기기</button>
</div>
);
};
Basic.propTypes = {
name: PropTypes.string.isRequired,
birth: PropTypes.number.isRequired,
lang: PropTypes.string,
};
Basic.defaultProps = {
lang: 'Javascript',
};
export default Basic;
컴포넌트 코드가 매우 단순해졌습니다. 함수 컴포넌트는 constructor가 없기에 state를 선언하는 방법이 다릅니다.
useState는 다음과 같이 선언합니다.
const [상태, 상태변경함수] = useState(초깃값);
const [hidden, setHidden] = useState(false);
예전처럼 setState 할 필요 없이, 상태마다 그 상태를 변경할 수 있는 함수를 같이 제공하기 때문에 값을 좀 더 간단하게 바꿀 수 있습니다.
예전 class에서는 상태가 여러 개일 때
this.state = {
name: 'a',
age: 15,
married: false,
};
이런 식으로 객체로 묶어서 표현했다면, hook에서는 상태 하나 하나를 개별적으로 묶는 것을 권장합니다. 물론 객체로 선언해도 되지만 개별적으로 묶는 게 렌더링 효율에서 이점이 더 많습니다.
const [name, setName] = useState('a');
const [age, setAge] = useState(15);
const [married, setMarried] = useState(false);
setMarried같은 상태변경함수도 setState처럼 이전 state 기반으로 값을 바꿀 수 있습니다.
setMarried((prev) => !prev); // false를 true로, true는 false로
setAge((prev) => prev + 1); // 나이를 1살 올림
상태변경함수를 통해 state가 바뀌었다면 알아서 함수컴포넌트가 다시 실행됩니다. 컴포넌트 내부가 실행되는데 useState는 다시 실행되지 않기에(정확히는 실행되지만 아무 일도 하지 않음) 상태값이 초깃값으로 되돌아가거나 하는 일은 없습니다. return되는 부분의 JSX를 비교한 뒤 달라지는 부분이 있다면 그 부분만 화면을 바꿉니다.
다음 시간에는 이벤트를 바인딩하는 useCallback hook에 대해서 알아보겠습니다.