[코딩온] 프론트엔드 입문 Day 41 (React state)
오늘은 React의 State에 대해서 배웠다. State라는 것의 개념 자체는 그렇게 어렵지 않았는데, 수업 끝나기 직전에 작성한 예시는 살짝 복잡한 코드였어서 이해하는데 시간이 조금 많이 걸렸다. 아직 배우는 단계니까 그럴 수도 있다고 긍정적으로 생각해야 하는데, 코드 하나 작성하려면 생각을 너무 오랫동안 해야하니까 자신감이 약간 떨어졌다.😢
이전 2개의 파트는 그렇게 어렵지도 않았고, 예전에 공부했던 것도 있어서 비교적 수월했지만, 이번 파트는 한번도 접해보지 않은걸 이제 하나씩 배우기 시작했으니까, 차근차근 천천히 잘 따라가보자..!

React - State
State는 유동적인 데이터를 다루기 위한 개체로서, '상태' 또는 '상태관리'라고 한다.
계속 변화하는 특정 상태에 따라 다르게 동작하여, state가 변하면 다시 렌더링을 한다.
💡 여기서 잠깐!
State와 Props의 정의는 지난 글에도 작성했지만 한번 더 짚어보자면,
- Props는 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달할 때 사용된다. (읽기 모드)
- State는 특정 컴포넌트가 갖는 상태, 동적인 값을 의미한다. 컴포넌트 내부에서 선언되고, 값을 변경하는 것도 내부에서만 가능하다. 참고로 State 기능은 과거에는 클래스형 컴포넌트에서만 사용할 수 있었지만, React Hook이 생기면서 함수형에서도 사용할 수 있게 되었고, 현재는 함수형 컴포넌트의 사용 비율이 높은 편이다.
클래스형 컴포넌트의 state
기본적으로는 React에서 Component 기능을 import 하고, Component 클래스를 상속받아서 사용한다.
(ex. class '클래스명' extends Component {~~} )
먼저 super 키워드와 constructor 함수를 사용하는 고전적인 방법은 아래 코드처럼 작성한다.
import { Component } from 'react';
export default class ClassState extends Component {
constructor(props) {
super(props); // comps 클래스에서 props 상속받는 중
this.state = {
banana: '바나나',
};
}
}
- ClassState라는 클래스는 Component 클래스로부터 super 키워드를 통해서 props를 상속받을 예정이다.
- 이 클래스의 상태(state)는 banana이고, 값으로는 '바나나'가 들어갈 것이다.
super 키워드와 constructor 함수가 없는 간단한 방법은 아래 코드처럼 작성한다.
※ constructor 없이 바로 state만 작성해도, constructor (props) { super (props) }가 자동으로 들어간다.
※ state 선언을 객체형으로 작성하여 값으로 '바나나'를 저장했기 때문에, setState 내부에도 객체형으로 들어간다.
import { Component } from 'react';
export default class ClassState extends Component {
state = {
banana: '바나나',
};
render() {
const { banana } = this.state;
return (
<>
<h2>클래스형 컴포넌트에서 state 사용</h2>
<button onClick={() => this.setState({ banana: 'yellow' })}>
영어로 변경!
</button>
<div>{this.state.banana}</div>
<div>{banana}</div>
</>
);
}
}
- (앞서 작성했던 코드랑 마찬가지로) ClassState라는 클래스는 Component 클래스로부터 props를 상속받을 것이다.
- 이 클래스의 상태(state)는 banana이고, 값으로는 '바나나'가 들어갈 것이다.
- 컴포넌트를 화면에 표시하기 위해 render()를 작성하고, 출력할 것들을 render() 내부에 return 키워드로 입력한다.
- setState는 앞으로 변경될 상태(값)이다. 여기서는 버튼을 클릭하면 banana라는 상태가 'yellow'로 변경된다.
함수형 컴포넌트의 state
앞서도 언급했듯, state 기능은 클래스형 컴포넌트에서만 사용할 수 있는 기능이었는데, React 16.8 버전 이후부터는 React Hook이 등장하면서 함수형 컴포넌트에서도 이 기능을 사용할 수 있게 되었다.
함수형 컴포넌트에서 state를 사용하는 가장 기본적인 방법은 아래 코드와 같다.
import { useState } from 'react';
export default function FuncState() {
const [apple, setApple] = useState('사과');
return (
<>
<h2>함수형 컴포넌트 state 사용</h2>
<div>이 컴포넌트는 useState로 작성</div>
<button onClick={() => setApple('apple')}>영어로 변경!</button>
<div>{apple}</div>
</>
);
}
- 가장 먼저 React에서 useState를 import해야 한다. 이 과정은 내가 앞으로 함수형 컴포넌트에서 state를 사용할거라고 선언하는 것이다.
- 컴포넌트 선언문 내부, return 위에서 useState의 정의를 내린다.
→ useState는 현재 상태와 setter 함수를 배열로 제공하므로, 구조분해할당하여 변수에 저장하고 바로 사용한다.
→ 하나의 선언문 안에 여러 개의 state를 만들고 사용할 수 있다. - useState 소괄호 안에 들어가는 값은 해당 state의 초기값이다.
- setter 함수에 매개변수로 들어가는 값은 앞으로 변경될 상태(값)이다. 위 코드에서는 초기값 '사과'가 setter 함수를 통해서 'apple'로 변경될 것이다.
함수형 컴포넌트로 state 사용하기 - 추가 실습
보통 블로그에는 이론적인 부분만 기록하기 때문에 사실 여기서 끝맺음해도 되지만, 이번에는 정말 확실히 이해하는게 중요할 것 같아서 수업 시간에 작성한 코드들을 조금 더 살펴보도록 하겠다!👀
// Number state를 1씩 증가시키는 버튼 만들기
import { useState } from 'react';
export default function FuncState() {
const [number, setNumber] = useState(0);
return (
<>
<div>{number}</div>
<button onClick={() => setNumber((prevNum) => {
alert(prevNum + 1);
return prevNum + 1;
})}>
+1
</button>
</>
);
}
- React에서 useState를 import하고, 함수형 컴포넌트의 기본 구조 작성까지는 앞선 코드들과 같다.
- 현재 상태(Number)와 변화될 상태(setNumber)를 배열로 받아와서 구조분해할당하고, state의 초기값은 0으로 지정한다.
- 버튼 태그에 onClick으로 변화될 상태를 연결해준다.
💡 여기서 잠깐!
단순하게 생각하면 setNumber (number+1)도 가능할 것 같지만, 안 되는 이유가 있다.
setNumber(number+1);
alert(number);
라고 작성해도, alert에는 1을 더하기 전의 값이 보이는데, 이는 setter 함수가 비동기적으로 동작하기 때문이다.
(number가 1을 더한 값으로 업데이트 되기 전에, alert 창이 먼저 띄워져서 원래 값이 보이는 것.)
이를 해결하기 위해서는 setter 함수의 인자로 업데이트할 값이 아니라 콜백을 전달하면 된다.
(해당 콜백의 인자는 원래 state 값이고, 여기에 1을 더하도록 작성)
→ setNumber((prevNum) => prevNum + 1);
// 버튼 클릭시 apple,사과 번갈아가며 변경
import { useState } from 'react';
export default function FuncState() {
const [showEng, setShowEng] = useState(true);
return (
<>
<button onClick={() => setShowEng(!showEng)}>
{showEng ? '한글' : '영어'}로 변경!
</button>
<div>{showEng ? 'apple' : '사과'}</div>
</>
);
}
- React에서 useState를 import하고, 함수형 컴포넌트의 기본 구조 작성까지는 앞선 코드들과 같다.
- 현재 상태(showEng)와 변화할 상태(setShowEng)를 배열로 받아와서 구조분해할당하여 변수에 담는다.
- useState의 초기값을 true로 지정하는건, 값이 번갈아가며 변경될 수 있도록 아래에 삼항연산자를 사용하기 때문이다.
- 버튼 태그에 onClick으로 setter 함수를 연결하는데, 인자로 '현재 상태를 부정하는 값'을 넣는다.
여기까지가 오늘 배운 내용이었다. 수업을 들으면서 바로 머릿속에 입력되지 않았던게, 블로그에 정리하면서 설명해보니 이해되는 느낌이다. 다수의 객체로 이루어진 배열 데이터를 React로 다루는 방법도 배웠는데, 거기에 추가적으로 오늘 수업 끝나기 직전 작성했던 어려운 코드까지 여기에 기록하면 글이 너무 길어질 것 같아서 다른 포스팅에 자세히 기록해보려고 한다.✍
총선 때문에 다음 수업까지 3일이나 텀이 생겼는데, 그동안 React와 더 빨리 친해질 수 있게 더 많은 자료를 찾아보고 열심히 연구해봐야겠다.
