React state & setState 개념 이해
: 동적인 데이터 처리할 때 state를 사용한다.
import React, { Component } from 'react';
class Counter extends Component {
state = {
number: 0
}
increase = () => {
this.setState({
number: this.state.number + 1
});
}
decrease = () => {
this.setState({
number: this.state.number - 1
});
}
render() {
return (
<div>
<div>카운터</div>
<div>값: {this.state.number}</div>
<button onClick={this.increase}>+</button>
<button onClick={this.decrease}>-</button>
</div>
);
}
}
export default Counter;
여기서 increase() 함수와 decrease() 함수를 아래와 같이 작성할 수도 있습니다.
increase() {
this.setState({
number: this.state.number + 1
});
}
decrease() {
this.setState({
number: this.state.number - 1
});
}
하지만, 이렇게 작성을 하면 버튼에 이벤트가 발생이 되었을 경우 this가 undefined 처리가 될 수도 있습니다.
첫 번째 코드에서처럼 화살표 함수 형태(ES6 문법)로 작성을 하든지 아니면 constructor로 처리를 하시면 됩니다.
constructor(props) {
super(props);
this.increase = this.increase.bind(this);
this.decrease = this.decrease.bind(this);
}
1. class 사용 시기
: state와 Lifecycle을 사용할 때 class를 사용합니다. Hook이 없었던 시절에는 함수형 컴포넌트에서 state와 lifecycle 관리를 못 했지만, 지금은 함수형 컴포넌트에서 Hook()을 사용하여 useState, useEffect을 활용하여 state와 Lifecycle 관리가 가능합니다.
// class fields를 사용하지 않는 경우
class Checkbox extends React.Component { // 이전에는 constructor를 정의하고 super(props)를 호출
constructor(props) {
super(props);
this.state = { hanPy: true };
};
...
};
// class fields를 사용하는 경우
class Checkbox extends React.Component {
state = { hanPy: true };
...
};
대부분 super와 constructor을 많이 사용한다. 하지만 클래스필드 문법을 사용하면 super(1)와 constructor를 사용하지 않아도 된다.
(1) super
: 자바스크립트에서는 super는 부모 클래스 생성자를 가리킨다. 리액트에서는 React.Component를 가리킨다.
핵심은 리액트에서는 super(props) 선언전까지 constructor에서 this 키워드를 사용할 수 없다. 그러나, 어떤 경우에는 super 키워드 안에 props를 작성하지 않아도 render 메서드에서 this.props를 사용할 수 있다.
리액트가 클래스 문법에 대한 지원이 추가 되었을때, 단지 ES6 클래스로써의 지원만을 한 것은 아니었다. 클래스의 넓은 범위의 추상화를 지원하는 것이 목표였다. 물론 리액트는 constructor가 실행된 후 this.props를 할당된다. 그러나 constructor에서 super()가 불려진 이후에도 this.props는 여전히 undefined 일 것이다. 디버깅을 위해 꼭 필요한 것은 하니지만 super(props)로 작성하는 것을 추천한다.
2. props와 state 비교
props: 부모 컴포넌트가 자식 컴포넌트에게 주는 값. 자식 컴포넌트는 props를 받아오기만 하고 직접 수정할 수는 없습니다.
state: 컴포넌트 내부에서 선언하면 내부에서 값 변경 가능합니다.
3. setStae
: 메소드에 this.setState라는 것이 있다. state에 있는 값을 바꾸기 위해서는 this.setState를 무조건 거쳐야 한다.
리액트에서는, 이 함수가 호출되면 컴포넌트가 다시 렌더링이 되도록 설계되어있습니다.
state = {
number : 0,
name : 'Lim'
}
this.setState({ number:1 })을 하면, Lim은 그대로 있고, namber가 0에서 1로 바뀐다.
그러나 setState는 객체의 깊숙한 곳까지는 확인하지 못한다.
state = {
number : 0,
name : {
first: "chul"
last: 'Lim'
}
}
※ first와 last 값을 업데이트 할 수 없습니다.
state 안에 객체가 들어있을 떄는 객체 내부의 값을 바꾸려면, 객체 내부에서 불러오고 싶은 위치를 재지정해야 한다.
this.setState({
number: 0,
name: {
...this.state.name,
last: "Lim"
}
});
… 은 자바스크립트의 전개 연산자입니다. 기존의 객체 안에 있는 내용을 해당 위치에다가 풀어준다는 의미입니다. 그다음에 우리가 설정하고 싶은 값을 또 넣어주면 해당 값을 덮어쓰게 됩니다.
4. setState 코드 문법
기존 작성한 코드
this.setState({
number: this.state.number + 1
});
this.state 조회 생략하는 문법 사용
this.setState(
(state) => ({
number: state.number
})
);
setState에 updater 함수를 만들어서 전달하는 문법 사용
this.setState(
({ number }) => ({
number: number + 1
})
);
비구조화 할당 문법 사용
- 비구조화 할당 문법은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.
const { number } = this.state;
this.setState({
number: number + 1
})
5. React에서 이벤트 설정 시 주의사항
<button onClick={this.increase}>+</button>
- 이벤트 이름은 camel Case로 설정
- 이벤트에 전달되는 값은 함수만 설정
- 만약에 this.increase()로 처리를 하면 Rendering을 할 때마다 해당 함수가 호출이 되어 계속 반복이 됩니다.
참고 글: 누구든지 하는 리액트 4편: props 와 state
'Programming 개발은 구글로 > Web[프론트엔드&백엔드]' 카테고리의 다른 글
[Web] React Hooks - useState, useEffect 등 (0) | 2022.06.29 |
---|---|
[Web] React의 LifeCycle API 알아보자 (0) | 2022.06.28 |
[Web] React props & defaultProps 개념이해 (0) | 2022.06.27 |
[Web] npm : 'npm' 용어가 cmdlet, 함수, 스크립트 파일 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다. 에러 발생 (0) | 2022.06.26 |
[Web] Node.js 개요와 설치방법 (0) | 2022.06.26 |
댓글