minghxx.blog
  • [처음 만난 리액트] section 6. State and Lifecycle
    2024년 03월 26일 02시 06분 37초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

     

    1. State와 Lifecycle의 정의

    🔎 State란?

    리액트 컴포넌트의 상태, 리액트 컴포넌트의 변경 가능한 데이터를 의미

     

    state는 개발자가 정의

    렌더링이나 데이터 흐름에 사용되는 것만 state에 포함

    state가 변경될 경우 컴포넌트가 재렌더링되기 때문에 성능 저하

    렌더링이나 데이터 흐름과 상관없는 값은 인스턴스 필드로 정의

     

    state는 자바스크립트 객체이다

    클래스 컴포넌트는 constructor 함수 가지고 있음(= 생성자), 클래스가 생성되면 실행됨

    this.state 부분이 현재 컴포넌트의 state를 정의하는 부분

    함수 컴포넌트에서는 useState라는 hook을 사용해서 정의함

     

    state는 직접 수정할 수 없다

    state는 렌더링과 관련이 있기 때문에 직접 변경하기보단 setter를 이용해서 변경

     

    🔎 Lifecycle 란?

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

    클래스 컴포넌트와 연관

    계속 존재하는 것이 아니라 흐름에 따라 생성되고 업데이트되다가 사라짐

    초록색 -> 클래스 컴포넌트 함수

    2. State 사용하기

    🔎 State 사용해보기

    📃 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 = {};
      }
    
      render() {
        return (
          <div style={styles.wrapper}>
            <span style={styles.messageText}>{this.props.message}</span>
          </div>
        );
      }
    }
    
    export default Notification;

    • 22라인 state : 현재는 아무런 데이터가 없음

     

    📃 NotificationList.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]);
            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;

    • 22~24라인 state : 생성자에서 앞으로 사용할 데이터를 state에 넣어 초기화 → 현재는 빈 배열을 넣었음

    27~40라인 componentDidMount : 1초마다 reservedNotifications에서 데이터를 하나씩 가져와 state에 데이터를 넣고 업데이트함

    33~35라인 setState : state 업데이트를 위해 setState 사용

     

    📃 index.js

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import reportWebVitals from './reportWebVitals';
    import NotificationList from './chapter_06/NotificationList';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <NotificationList />
      </React.StrictMode>
    );
    
    reportWebVitals();

     

    📊 결과

    매초마다 알림이 하나씩 추가됨

     

    🔎 Lifecycle method 사용해보기

    📃 Notification.jsx 수정

    console.log 추가

    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 수정

    id 추가

    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 {
            clearInterval(timer);
          }
        }, 1000);
      }
    
      render() {
        return(
          <div>
            {this.state.notifications.map((notification) => {
              return (
                <Notification 
                  key={notification.id}
                  id={notification.id}
                  message= {notification.message} />
              );
            })}
          </div>
        );
      }
    }
    
    export default NotificationList;

     

    📊 결과

     

     

     

     

    728x90
    댓글