게시글은 리액트 공부용이며 출처를 제시합니다.
출처: 소플의 처음 만난 React, 리액드를 다루는 기술, 모던 자바스크립트 deep dive
리액트 컴포넌트의 상태
리액트 컴포넌트의 변경 가능한 데이터
렌더링이나 데이털 흐름에 사용되는 값만 state에 포함시켜야 한다.
WHY?
State가 변경될 경우 컴포넌트가 재렌더링 되기 때문에 렌더링과 데이터 흐름에 관련 없는 값을 포함하면 컴포넌트가 다시 렌더링 되어 성능을 저하 시킬수 있다.
리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.
State는 자바스크립트의 객체이다.
class LikeButton extends Component{
constructor(props){
super(props);
this.state = {
liked: false
};
}
}
LikeButton이라는 리액트 클래스 커포넌트
모든 클래스 컴포넌트에는 constructor라는 이름의 함수가 존재한다.
생성자라는 의미이며 클래스가 생성될 때 실행되는 함수이다.
생성자 코드에 this.state
는 현재 컴포넌트의 state를 정의하는 부분이다.
클래스 컴포넌트의 경우 state를 생성자에서 정의한다.
함수 컴포넌트에서는 state를 useState()
라는 훅을 사용해서 정의한다.
state는 직접적인 변경이 불가능하다.
//state 직접 수정은 잘못된 방법
this.state = {name: "joah"} => X
//setState 함수를 통한 수정 정상적인 방법
this.setState({name: "joah"}) => O
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
//state의 초깃값 설정
this.state = { number: 0 };
}
render() {
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+ 1
</button>
</div>
);
}
}
컴포넌트에 state를 설정할 때는 constructor
메서드를 작성하여 설정
컴포넌트의 생성자 메서드
constructor
를 작성할 때는 반드시 super
를 호출해야 한다.super -> constructor -> class Counter
this.state
값에 초깃값을 설정한다. state
는 객체 형식
render
함수에서 현재 state
를 조회할 때는 this.state
onClick
이벤트롤 설정할 함수를 넣어 줄 때는 화살표 함수를 작성한다.
this.setState
라는 함수를 사용하여 state
를 변경해야하니깐state 객체 안에는 여러 값이 있을 수 있다.
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
this.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 });
}}
>
+ 1
</button>
</div>
);
}
}
export default Counter;
state 객체에 fixedNumber
추가
버튼을 클릭했을 때 바뀌는 값은 number
일 뿐!
state의 초깃값을 지정하기 위해 constructor
메서드를 선언했지만 또 다른 방식으로도 state의 초깃값을 지정할 수 있다.
아주 간단한 방법으로 ellie's dream coding에서도 사용하고 있는 방식
import React, { Component } from "react";
class NoConstructor 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 });
}}
>
+ 1
</button>
</div>
);
}
}
export default NoConstructor;
this.setState()
에 객체 대신 함수 인자 전달this.setState()
를 사요하여 state 값을 업데이트할 때는 상태가 비동기적으로 업데이트 된다.
만약 onClick
에 설정한 함수 내부에서 this.setState()
를 두번 호출하면?
onClick={()=>{
this.setState({number: number + 1});
this.setState({number: this.state.number + 1});
}}
값이 2번 올라가기를 기대하지만 1번밖에 올라가지 않는다.
this.setState
를 사용한다고 해서 state 값이 바로 바뀌지는 않는다.
📢 해결
this.setState
를 사용할 때 객체 대신 함수를 인자로 넣어주는 것!
this.setState((prevState, props)=>{return{업데이트내용}})
<button
onClick={() => {
this.setState({ number: number + 1 });
this.setState((prevState) => {
return { number: prevState.number + 1 };
});
}}
>
+ 1
</button>
//화살표 함수에서 객체를 바로 리턴하려면 중괄호를 생략한다.
<button
onClick={() => {
this.setState({ number: number + 1 });
this.setState(prevState => ({
number: prevState.number + 1 ;
}));
}}
>
+ 1
</button>
prevState => ({ })
형태로 작성하면 바로 객체를 반환할 수 있다.
this.setState()
가 끝난 후 특정 작업 실행하기값을 업데이트하고 난 다음에 특정 작업을 하고 싶을 때는 setState
의 두 번째 파라미터로 콜백 함수를 등록하여 작업을 처리할 수 있다.
<button
onClick={() => {
this.setState({ number: number + 1 }, () => {
console.log("방금 state가 호출됨");
console.log(this.state);
});
}}
>
+ 1
</button>