react 수업

6.state와 lifecycle

gongmille 2024. 9. 3. 12:48

-state

리액트에서 state는 리액트 컴포넌트의 데이터 상태. 리액트 컴포넌트의 변경 가능한 데이터의 상태.

>>렌더링이나 데이터 흐름에 사용되는 값만 state에 포함시켜야 한다<<

state = 자바스크립트 객체

 

//state를 직접 수정 (X)
this.state = { name : 'Inje'};

//state 간접 수정(O)
this.setState({ name : 'Inje' });

 

-lifecycle

리액트 컴포넌트의 생명 주기. 생성되는 시점과 사라지는 시점이 정해져있다는 의미.

생성 : mounting 

렌더링 : updating

삭제 : unmounting - 상위 컴포넌트에서 더이상 표출 되지 않을 때를 의미

 

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

 

-실습

 

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 = {};
    }

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

export default Notification;

Notification.jsx

 

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

const reservedNotifications = [
    {
        message : "안녕하세요, 오늘의 일정을 알려드립니다."
    },
    {
        message : "점심식사 시간입니다."
    },
    {
        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]);
                
                //state 업데이트
                this.setState({
                    notifications : notifications
                });
            } else {
                clearInterval(timer);
            }
        },1000);
    }

    render() {
        return(
            <div>
                {this.state.notifications.map((notification) => {
                    return <Notification message={notification.message}/>;
                })}
            </div>
        );
    }
}

export default NotificationList;

NotificationList.jsx

 

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

import NotificationList from './chapter06_state/NotificationList';


const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <NotificationList />
  </React.StrictMode>
);

// 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();

index.js

 

테스트 중 

Each child in a list should have a unique "key" prop 이라는 오류가 떴다. 찾아보니 순차 나열시 독립적인 key값을 부여하지 않으면 나오는 에러라고 한다.

 

const reservedNotifications = [
    {   
        code : "1",
        message : "안녕하세요, 오늘의 일정을 알려드립니다."
    },
    {
        code : "2",
        message : "점심식사 시간입니다."
    },
    {
        code : "3",
        message : "이제 곧 미팅이 시작됩니다."
    }
];
...
render() {
        return(
            <div>
                {this.state.notifications.map((notification) => {
                    return <Notification key={notification.code} message={notification.message}/>;
                })}
            </div>
        );
    }
}
...

NotificationList.jsx

 

reservedNotifications에 code를 추가해 값을 하나씩 주고 아래 렌더링 할때 해당 값을 key 라는 속성에 넣도록 수정하니 콘솔 오류는 더 이상 뜨지 않았다.

 

더불어 1과 2가 한번에 뜨는 현상이 있었다. 커뮤니티를 보니 같은 증상을 물어보는 사람들이 있었고 해당 답으로는 index.js에서 감싸고 있는 React.StricMode에서 문제가 생긴 것이라고 한다.

React.StricMode는 개발 모드일때 잠재적인 버그를 찾을 수 있게 해주는 것으로 배포 시에는 정상작동이 된다고 한다.

React.StricMode를 지우고 실행하면 정상 작동이 된다고 한다.

(해당 부분은 18버전 이후부터 작동되는 것이기 때문에 최근 버전에서는 자동적으로 나올 수 밖에 없는 현상이라고 한다.)

 

 

초에 따라 하나씩 추가되는 모습을 확인 할 수 있다.

 

해당 코드를 바탕으로 lifrcycle method를 사용해보자

 

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

        this.state = {};
    }
    
    //컴포넌트가 마운트 된 이후
    componentDidMount() {
        console.log(`${this.props.id} DidMount called`);
    }

    //컴포넌트가 업데이트가 된 이후
    componentDidUpdate() {
        console.log(`${this.props.id} DidUpdate called`);
    }

    //컴포넌트가 언마운트 된 이후
    componentWillUnmount() {
        console.log(`${this.props.id} WillUnmount called`);
    }

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

Notification.jsx

 

...
    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]);
                
                //state 업데이트
                this.setState({
                    notifications : notifications
                });
            } else {
                //notifications 비우기 = 언마운트 시키기
                this.setState({
                    notifications : []
                });

                clearInterval(timer);
            }
        },1000);
    }

    render() {
        return(
            <div>
                {this.state.notifications.map((notification) => {
                    return <Notification key={notification.code} id={notification.code} message={notification.message}/>;
                })}
            </div>
        );
    }
}
...

NotificationList.jsx

 

해당 부분을 적용하고 개발자모드를 켜서 콘솔을 확인해보면 다음과 같은 로그가 떠 있는 걸 확인할 수 있다.

 

'react 수업' 카테고리의 다른 글

8.event  (0) 2024.09.04
7.hooks  (1) 2024.09.03
5. components, props  (0) 2024.09.02
4. rendering elements  (0) 2024.08.31
3. jsx와 createElement  (0) 2024.08.31