2021. 8. 22. 22:05ㆍWEB/React
State
props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며,
컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다
(props를 전달받은 자식 컴포넌트는 props의 내용을 절대로 수정할 수 없다)
즉, props를 변경하기 위해서는 부모 컴포넌트가 바꾸어주어야 비로소 변경이 될 수 있다
이러한 문제를 해결하기 위해 State를 사용하게 된다
State는 크게 두 종류로 클래스형 컴포넌트의 state, 함수형 컴포넌트의 state가 있다
클래스형 컴포넌트
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
number: 0
};
}
클래스형 컴포넌트에 state를 설정할 때는 constructor 메서드를 작성해야 한다
컴포넌트의 생성자 메서드로 컴포넌트가 실행될 때 constructor라는 함수가 있다면,
가장 먼저 실행되어 초기화를 담당하게 된다
(사용시에는 반드시 super(props)를 함께 사용되어야 한다)
this.state 값에 초깃값을 설정해 줄 수 있으며, 컴포넌트의 state는 객체 형식이어야 한다
render() {
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1});
}}
> +1 </button>
</div>
)
}
render 함수에서 현재 state를 조회할 때는 this.state를 조회하면 된다
button 앞에 onClick의 값으로 props를 넣어주고, 버튼이 클릭될 때 호출시킬 함수를 설정한다
(JS에서 이것을 이벤트라고 한다)
이벤트로 설정할 함수를 넣어 줄 때는 화살표 함수(Arrow function)을 사용해서 넣어야 한다
함수 내부에서는 this.setState 함수를 사용했는데, 해당 함수가 state 값을 변경시켜주게 된다
App.js
import React from "react";
import Counter from "./counter";
function App() {
return <Counter />;
}
export default App;
리액트 브라우저에서 아래와 같은 결과를 확인했다면 정상적으로 state가 동작하고 있는 것이다
이러한 특징을 가진 state 객체 안에는 하나의 데이터가 아닌, 여러 데이터를 사용할 수 있다
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
fixedNumber: 0 // 변경점 1
};
}
render() {
// 변경점 2, 객체 안에 fixedNumber 추가
const { number, fixedNumber } = this.state; // state를 조회할 때는 this.state로 조회
return (
<div>
<h1>{number}</h1>
<h1>변경되지 않는 데이터: {fixedNumber}</h1> // 변경점 3
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정
onClick={() => {
// this.setState를 사용하여 state에 새로운 값을 넣을 수 있다
this.setState({ number: number + 1});
}}
> +1 </button>
</div>
)
}
}
export default Counter;
state안에 또 다른 값인 fixedNumber를 추가해주었다
this.state = {
number: 0,
fixedNumber: 0
};
render() 안을 보면 알 수 있지만, 지금 당장 fixedNumber를 추가해준 부분에 대한 별다른
변경점이 생기거나, 다른 동작을 수행한다거나 그런건 전혀 아니다
위에서 처음 state를 설명할 때 언급했었지만, 결과적으로 state의 값은 setState가 결정한다
그런데 현재 변경된 코드에서 setState의 선언은 변경된 부분이 없다
this.setState({ number: number + 1});
이벤트가 발생할 때마다 number + 1을 number에 반복하여 재할당 해주고 있을 뿐이다
실제 결과 또한 fixedNumber는 0에서 전혀 증가하지 않는 것을 볼 수 있다
여기까지 잘 이해가 되었다면 fixedNumber의 값 또한 이벤트를 통해 변경하는 것은 어렵지않다
( 아래 코드를 보기 전 +1 버튼을 눌렀을 때 number와 동일하게 변경될 수 있도록 시도해보자)
onClick={() => {
this.setState({
number: number + 1,
fixedNumber: fixedNumber + 1
});
}}
이벤트 발생시 변경점을 감지하여 state값을 바꾸어줄 setState 안에서 값을 변경하면 된다
지금까지 state의 초깃값 지정을 위해서 constructor 메서드를 이용해서
리액트의 Component 클래스가 지닌 생성자 함수를 호출해서 사용해왔다
이제부터는 이와 같은 방식이 아닌, 아래와 같은 방식으로 state를 사용할 것이다
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h1>이젠 나도 변경 ! : {fixedNumber}</h1>
<button
onClick={() => {
this.setState({
number: number + 1,
fixedNumber: fixedNumber + 1
});
}}
> +1 </button>
</div>
)
}
}
export default Counter;
더 이상 constructor를 통한 초기화를 진행하지 않고, 곧바로 state를 통해 초깃값을 지정하게 된다
this.setState에 객체 대신 함수를 인자로 전달하는 방법
this.setState를 사용해서 state 값을 업데이트할 때는 상태가 비동기적으로 업데이트 된다
여기서 비동기에 대한 부분은 뒤에서 좀 더 자세하게 다루어 볼 예정
지금은 "요청과 결과가 동시에 일어나지 않는다" 정도로 생각하자
onClick={() => {
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1});
}}
위 코드를 보면, setState를 두 번 사용했음에도 클릭시에는 숫자가 1씩 더해지는 것을 확인할 수 있다
이유는 첫 번째 setState에서 증가시킨 number를 두 번째 setState에서 Overwrite 해버리기 때문이다
이러한 문제를 해결하고 싶을 때 인자 값으로 함수를 넣어줄 수 있으며, 사용법은 아래와 같다
this.setState((State, props) => {
return {
// setState를 통해 변경할 내용
}
}
State는 기존 상태를 의미하며, props는 현재 상속받고 있는 props를 가리킨다
(변경과정에서 props가 존재하지 않거나, 필요하지 않다면 생략해도 무관하다)
onClick={() => {
this.setState((State) => {
return {
number: State.number + 1
};
});
this.setState(State => ({
number: State.number + 1
}));
}}
* 위 두 코드는 완전히 동일한 기능을 하는데 차이는 아래 코드는 함수에서 바로 객체를 반환한다는 의미
this.setState의 업데이트 동작이 끝난 직후 특정한 작업을 수행할 수도 있다
setState의 두 번째 파라미터로 콜백(Callback)함수를 등록하여 작업 처리가 가능하다
onClick={() => {
this.setState(
{
number: number + 1
},
() => {
console.log("setState 호출")
console.log(this.state);
}
);
}}
콜백함수란 특별한 선언이나 자체적인 문법이 있는 것이 아니다
이름 그대로 나중에 실행되는 함수로, 호출 방식에 따라 특정 시점에 도달했을 때 실행되게 된다
'WEB > React' 카테고리의 다른 글
16. React (Re: act #4) (0) | 2021.09.05 |
---|---|
15. React (Re: act #3.5) (0) | 2021.08.23 |
13. React (Re: act #2) (0) | 2021.08.18 |
12. React (Re: act #1.5) (0) | 2021.08.17 |
11. React (Re: act #1) (0) | 2021.08.15 |