기록하는 개발자

<React 파헤치기-12> 컴포넌트 - 4. state 본문

Web/React

<React 파헤치기-12> 컴포넌트 - 4. state

밍맹030 2021. 12. 16. 14:42
728x90

property의 특징이 컴포넌트 내부에서 값을 변경할 수 없다는 점이었다면,

state는 반대로 컴포넌트 내부에서 값을 변경해야 하는 경우 사용한다.

 

state

값을 변경하거나 저장할 수 있는 객체로 보통 버튼 클릭, 값 입력 등의 이벤트와 함께 사용된다.

 

state 사용 시 주의점

1. 반드시 생성자(constructor)에서 초기화 해야한다.
2. state 값을 변경할 때는 반드시 setState()를 사용해야한다.
3. setState()는 비동기로 처리되며 setState() 이후로 연결된 함수들의 실행이 완료된 시점에 화면 동기화 과정을 거친다.

 

 

state를 변경할 때 setState를 사용해야하는 이유

setState() 함수를 쓰지 않고 state를 변경하는 것이 불가능한 것은 아니다.

그러나 state를 강제로 변경한다고 해도 render() 함수가 재호출 되지 않기 때문에 의미가 없다.

render() 함수가 화면을 그려주는 시점은 리액트 엔진이 정하기 때문이다.

그러나 setState() 함수를 호출하여 state 값을 변경하면, 리액트 엔진이 자동으로 render() 함수를 호출한다.

따라서 화면에 변경된 state의 값을 새로 출력할 수 있다.

 

 

예시를 통해 컴포넌트에서의 state 사용을 알아보자

import React from 'react';

class testState extends react.Component {
	constructor(props){
    	super(props);
        
        //state 정의
        this.state = {
            isLoading : true,
            printString : 'still loading...',
        };
        
    	this.handleLoading = this.handleLoading.bind(this);
        // 5000ms(5초)후 callback 함수인 handleLoading을 실행한다. 
    	setTimeout(this.handeLoading, 5000);
    }
    
    handleLoading(){
    	const data = 'complete loading!';
        const { printString } = this.state;
        
        this.setState({
            isLoading : false,
            printString : data + printString,
        });
    }
    
    render(){
    	return(
        	<span> 로딩중 : {String(this.state.isLoading)} </span>
        	<span> 결과 : {this.state.printString} </span>
        )
    }
}

export default testState;
import React from 'react';
import testState from './testState';

class App extends React.Component{
    render(){
    	return(
      	    <div> <testState/> </div>
        );
    }
}
export default App;

결과 화면

setState 함수의 인자로 함수를 전달하면 이전 state값을 prevState를 통해 쉽게 읽어올 수 있다.

아래 코드는 prevState를 사용하여 위 예시의 handleLoading 함수를 수정한 버전이다.

handleLoading(data){
    this.setState(function(prevState){
        const newState = {
            isLoading : false,
            printString : data + prevState.printString,
        };
        return newState;
    });
}
728x90