React, State 사용하기, Notification List

2024. 12. 2. 17:23웹 개발

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 {
    // 생성자: props 초기화
    constructor(props) {
        super(props); // props 를 상위 클래스에 전달
        this.state = {}; // 상태는 현재 사용하지 않음
    }

    // 컴포넌트가 화면에 처음 렌더링된 후 호출
    componentDidMount() {
        console.log(`Notification ${this.props.id}가 화면에 추가되었습니다.`);
    }

    // 컴포넌트가 업데이트된 후 호출
    componentDidUpdate(prevProps) {
        console.log(`Notification ${this.props.id}가 업데이트되었습니다.`);
        console.table({ 이전: prevProps, 현재: this.props });
    }

    // 컴포넌트가 화면에서 제거되기 직전에 호출
    componentWillUnmount() {
        console.log(`Notification ${this.props.id}가 화면에서 제거되었습니다.`);
    }

    // 렌더링: 화면에 표시할 UI 정의
    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: "이제 곧 미팅이 시작됩니다." },
];

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

        // 초기 상태: 표시할 알림이 없음
        this.state = {
            notifications: [],
        };

        // 타이머를 관리하기 위한 변수
        this.timer = null;
    }

    // 컴포넌트가 화면에 처음 렌더링될 때 실행
    componentDidMount() {
        this.timer = setInterval(() => {
            const currentCount = this.state.notifications.length;

            // 더 추가할 알림이 있을 경우
            if (currentCount < reservedNotifications.length) {
                this.setState((prevState) => ({
                    notifications: [
                        ...prevState.notifications,
                        reservedNotifications[currentCount],
                    ],
                }));
            } else {
                // 모든 알림이 표시되었으면 초기화
                clearInterval(this.timer);
                this.setState({ notifications: [] });
            }
        }, 1000); // 1초 간격으로 실행
    }

    // 컴포넌트가 화면에서 제거되기 직전에 실행
    componentWillUnmount() {
        // 타이머 정리
        if (this.timer) {
            clearInterval(this.timer);
        }
    }

    // 화면에 알림 리스트를 렌더링
    render() {
        return (
            <div>
                {this.state.notifications.map((notification) => (
                    <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 PlayGround from "./chapter_00/PlayGround";

import NotificationList from "./chapter_06/NotificationList";

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

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

reportWebVitals();

 

결과