본문 바로가기

클라이언트/React
[리액트(React)] State, Lifecycle

// State

- Component의 변경 가능한 데이터

- 개발자가 직접 정의한다.

- 렌더링이나 데이터 흐름에 사용되는 값만 포함해야 한다.
   > 불필요한 컴포넌트 렌더링 방지

- JavaScript 객체

- 함수형 컴포넌트, 클래스형 컴포넌트에서 모두 사용된다.


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;

 

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) => (
          <Notification message={notification.message} />
        ))}
      </div>
    );
  }
}

export default NotificationList;

// 기존의 state를 기반으로 state 업데이트하기

기존의 state가 아래와 같을 때,

const [isEditing, setIsEditing] = useState(false);


단순하게 state를 업데이트 하려면 값을 바로 바꿔서 set함수에 넣어주면 된다고 생각할 수 있다.

setIsEditing(!isEditing);


그런데 리액트는 state에 대한 변화의 일정을 조율하기 때문에 state update가 즉각적으로 수행되지 않는다.
만약 state를 연속해서 두 번 update하면 결과는 어떻게 될까?

setIsEditing(!isEditing);
setIsEditing(!isEditing);


초기값이 false 이므로 false -> true -> false 로 최종값이 false여야 한다.

그런데 렌더링된 state는 true가 된다.

리액트가 state 변경을 즉각적으로 실행하지 않았기 때문에, 두 번째 줄의 setIsEditing(!isEditing)에서 isEditing도 초기값인 false를 기준으로 true로 변경되기 때문이다.

이를 해결하기 위해서는 set함수에 값을 함수 형태로 넘겨주어야 한다.

setIsEditing((editing) => !editing);


함수 형태로 넘겨줄 때, 매개변수는 isEditing 값을 넘겨주게 되기 때문에 !isEditing과 로직 자체는 같다.

그러나 이때는 연달아 실행되더라도 예정된 update가 실행되고 다음 것이 실행되기 때문에 state가 의도대로 update된다.

※ 만약 state가 객체나 배열이라면, 해당 state를 업데이트할 때 변경 불가능하게 하는 것이 좋다.
이전 상태를 하나 복제해서 새 갤체 또는 배열로 저장해 놓고 복제된 버전을 수정한다.

'클라이언트 > React' 카테고리의 다른 글

[리액트(React)] 이벤트 핸들러  (0) 2024.01.04
[리액트(React)] Hook  (2) 2024.01.03
[리액트(React)] Component, Props  (1) 2023.12.29
[리액트(React)] Elements Rendering  (0) 2023.12.28
[리액트(React)] JSX  (0) 2023.12.27