본문 바로가기
개발로그/React

소플의 처음 만난 리액트_실습4

by 쩜징 2023. 7. 11.

소플의 처음 만난 리액트_실습4


State

리액트 컴포넌트의 변경 가능한 데이터

컴포넌트를 개발하는 개발자가 직접 정의해서 사용

state가 변경될 경우 컴포넌트가 리렌더링 됨

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

 

State의 특징

자바스크립트 객체 형태로 존재

직접적인 변경이 불가능 함

- 클래스 컴포넌트

  생성자에서 모든 state를 한 번에 정의

  state를 변경하고자 할 때에는 꼭 setState()함수를 사용해야 함

- 함수 컴포넌트

  useState() 훅을 사용하여 각각의 state를 정의

  각 state별로 주어지는 set함수를 사용하여 state 값을 변경

 

생명주기

리액트 컴포넌트의 생명주기

 

마운트 componentDidMount()

- 컴포넌트가 생성될 때

 

업데이트 componentDidUpdate()

- 컴포넌트의 props가 변경될 때

- setState() 함수 호출에 의해 state가 변경될 때

- forceUpdate()라는 강제 업데이트 함수가 호출될 때

 

언마운트 componentWillUnmount()

- 상위 컴포넌트에서 현재 컴포넌트를 더 이상 화면에 표시하지 않게 될 때

 

컴포넌트는 계속 존재하는 것이 아니라 시간의 흐름에 따라 생성되고 업데이트 되다가 사라지는 과정을 겪음

 


State와 생명주기 함수 사용하기 실습 !!!

//Notification.jsx

import React from "react";

const styles = {
    wrapper : {
        margin:8,
        padding:8,
        display:"flex",
        flexDirection:"row",
        border:"1px solid grey",
        borderRadius:"16",
    },
    massageText : {
        color:"black",
        fontSize:16,
    },
};

//클래스 컴포넌트 - 생성자에 state를 정의
class Notification extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (
            <div style={styles.wrapper}>
                <span style={styles.massageText}>
                    {this.props.message}
                </span>
            </div>
        );
    }
}
export default Notification;
//NotificationList.jsx

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

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

var timer;
//1초마다 메세지가 화면에 뜨도록 설정
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 {
                clearInterval(timer);
            }
        },1000);
    }

    render() {
        return (
            <div>
                {this.state.notifications.map((notification)=> {
                    return <Notification message={notification.message} key={notification.message}/>
                })}
            </div>
        );
    }
}
export default NotificationList;
//index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import NotificationList from "./chapter_06/NotificationList";
import reportWebVitals from "./reportWebVitals";

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

실행 화면(React Developer Tools 기능 사용)

//Notification.jsx 수정

import React from "react";

const styles = {
    wrapper : {
        margin:8,
        padding:8,
        display:"flex",
        flexDirection:"row",
        border:"1px solid grey",
        borderRadius:"16",
    },
    massageText : {
        color:"black",
        fontSize:16,
    },
};

class Notification extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
    }
    
    //생명주기 함수 사용!
    //백틱으로 감싸는 것에 주의하기! id로 구분
    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.massageText}>
                    {this.props.message}
                </span>
            </div>
        );
    }
}
export default Notification;
//NotificationList.jsx 수정

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

//식별할 id 값 추가
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 {
            	//메세지를 다 띄우고 나면 setState()를 사용해 빈 배열로 만들 코드!
                this.setState({
                    notifications: [],
                });
                clearInterval(timer);
            }
        //1초는 너무 빠른 것 같아서 3초로 변경해서 확인했다.
        },3000);
    }

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

실행 화면

** 생명 주기 함수는 현재 잘 사용하지 않지만 Mount-Update-Unmount되는 과정들을 알아두면 좋을 것 같다.

 

반응형

댓글