이롭게 현명하게

[React] 리액트 State란? 본문

웹 개발/React

[React] 리액트 State란?

dev_y.h 2024. 1. 15. 18:08
728x90
반응형

※ 본 포스팅은 윈도우11 환경에서 인프런 강의를 수강하며 정리한 내용입니다.

 


 

목차

 

State란?

Lifecycle이란?

예시코드

 


 


[State란?]

state는 상태라는 뜻을 가지고 있다.

state 뜻

리액트에서의 state는 리액트 Component의 상태를 의미한다.

상태라는 단어가 정상, 비정상을 나타내는 것이라기보다 리액트 Component의 데이터라는 의미가 더 가깝다.

리액트에서의 State : React Component의 변경 가능한 데이터

이 state는 사전에 미리 정해진 것이 아니라 React Component를 개발하는 각 개발자가 직접 정의해서 사용한다.

 

자바스크립트에서는 변수를 사용한다.

리액트에서는 상태(state)를 사용한다고 생각하면 이해하기 쉽다.

 

 

State를 정의할 때 중요한 점은 꼭 렌더링이나. 데이터 흐름에 사용되는 것만 state에 사용해야 한다.

State가 변경될 경우 Component가 재렌더링되기 때문에 렌더링과 데이터 흐름에 관련 없는 값을 포함하면 불필요한 경우에 Component가 다시 렌더링 되어 성능을 저하시킬 수 있기 때문이다.

그래서 렌더링과 데이터 흐름에 관련 있는 값만 State에 포함하도록 해야 하며 그렇지 않은 값은 Component의 인스턴스 필드로 정의하면 된다.

 

State는 자바스크립트 객체이다.

리액트 State는 따로 복잡한 형태가 있는 것이 아닌 그냥 하나의 자바스크립트 객체이다.


 

class LikeButton extends React.Component{
	constructor(props){
    	super(props);
        
        this.state={liked:false};
    }
    
    ...
}

LikeButton이라는 리액트 Class Component를 나타낸 것이다.

모든 Class Component에는 constructor라는 이름의 함수가 존재하는데 생성자라는 의미를 가지고 있어 클래스가 생성될 때 실행되는 함수다.

this.state={liked:false};

this.state : 현재 Component의 state를 정의하는 부분이다.

Class Component의 경우 state를 생성자에서 정의한다.

Class Component는 state를 useState라는 Hook을 사용해서 정의하게 된다.

 

※ State는 직접 수정할 수 없다. 직접 수정하면 안 된다.

이렇게 정의한 state는 정의된 이후 일반적인 자바스크립트 변수를 다루듯이 직접 수정할 수는 없다.

// state를 직접 수정(잘못된 사용법)
this.state = {name:"react"};

// setState 함수를 통한 수정 (정상적인 사용법)
this.setState({name:"react"});

state를 직접 수정할 수는 있지만 그렇게 해서는 안되기 때문에 애초에 state는 직접적인 변경이 불가능하다.

리액트에서의 state는 Component의 렌더링과 관련 있기 때문에 마음대로 수정하게 되면 개발자가 의도한 대로 작동하지 않을 가능성이 있다.

state를 변경하고자 할 때는 꼭 setState라는 함수를 사용해야 한다.

 


[Lifecycle이란?]

Lifecycle은 생명주기를 말한다.

사람은 태어나서 인생을 살다가 나이가 들어 죽는 생명주기를 가지고 있다.

React Component도 마찬가지로 생명주기가 있다.

Component가 생성되는 시점과 사라지는 시점이 정해져 있다.

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

 

 

<Mounting>

사람이 태어나는 시기로 리액트에서는 Component가 생성되는 시점이다.

Class Copmonent를 사용할 경우 Component의 constructor 즉 생성자가 실행된다.

생성자에서는 Component의 state를 정의하게 된다.

Component가 렌더링 되며 이후에 componentDidMount함수가 호출된다.

 

<Updating>

태어난 사람은 각자의 인생을 살아간다.

사람은 인생을 살아가는 동안 신체적, 정신적 변화를 겪는다.

React Component도 생애 동안 변화를 겪으면서 여러 번 렌더링 된다.

이를 React Component가 업데이트(Update)되는 과정이라고 할 수 있다.

Update과정에서는 Component의 props가 변경되거나 setState함수 호출에 의해 state가 변경되거나 falseUpdate라는 강제 업데이트 함수 호출로 인해 Copmonent가 다시 렌더링 된다.

 

<Unmounting>

인생을 살아가던 사람은 나이가 들어 죽는다.

React Component도 언젠가는 사라지는 과정을 겪게 되는데 이 과정을 unmount라고 부른다.

Component의 unmount는 상위컴포넌트를 더 이상 화면에 표시하지 않게 될 때 unmount 된다.

 


이 외에도 다른 생명주기 함수가 존재한다.

Component가 계속 존재하는 것이 아니라 시간의 흐름에 따라 생성되고 업데이트되다가 사라진다.

 

 

 


[예시코드]

// Notification.jsx

import React from "react";

const styles = {
    wrapper : {
        margin:8,
        padding:8,
        display : "flex",
        flexDirection:"row",
        border:"1px solid grey",
        borderRadius:16,

    },
    messageText:{
        color:"black",
        fontSize:16,
    },
};

class Notification extends React.Component{
    constructor(props){
        super(props);
        this.state={};
    }

    componentDidMount(){
        console.log(`${this.props.id} componentDidMount() called.`)
    }

    componentDidUpdate(){
        console.log(`${this.props.id} componentDidUpdate() called.`)
    }

    componentWillUnmount(){
        console.log(`${this.props.id} componentWillUnmount() called.`)
    }



    render(){
        return(
            <div style={styles.wrapper}>
                <span style={styles.messageText}>{this.props.message}</span>
            </div>
        );
    }
}

export default Notification;
// NotificationList.jsx

import React from "react";
import Notification from "./Notification";

const reservedNotifications=[
    {
        id:1,
        message:"안녕하세요, 오늘 일정을 알려드립니다.",
    },
    {
        id:2,
        message:"점심식사 시간입니다.",
    },
    {
        id:3,
        message:"이제 곧 미팅이 시작됩니다.",
    },
];

var timer;

class NotificationList extends React.Component{
    constructor(props){
        super(props);

        this.state={
            notifications:[],
        };
    }

    componentDidMount(){
        const {notifications}=this.state;
        timer=setInterval(()=>{
            if(notifications.length < reservedNotifications.length){
                const index=notifications.length;
                notifications.push(reservedNotifications[index]);
                this.setState({
                    notifications: notifications,
                });
            }else{
                this.setState({notifications:[],});
                clearInterval(timer);
            }
        },1000);
    }
    componentWillUnmount() {
        if (timer) {
            clearInterval(timer);
        }
    }
    render(){
        return(
            <div>
                {this.state.notifications.map((notification)=>{
                    return <Notification 
                        key={notification.id}
                        id={notification.id}
                    message={notification.message}/>;
                })}
            </div>
        );
    }
}

export default NotificationList;
// index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import NotificationList from './chapter06/NotificationList';


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <NotificationList/>
  </React.StrictMode>
  ,  document.getElementById('root')
  
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

 

728x90
반응형
Comments