인프런 커뮤니티 질문&답변

권예준님의 프로필 이미지
권예준

작성한 질문수

처음 만난 리액트(React)

NotificationList.jsx 챕터 6장 실습 내용 질문 - 동시에 2개씩 나옴

해결된 질문

작성

·

1K

7

요약:
3개가 각각 1-1-1 로 1초 간격으로 나와야 하지만, 2-1 로 나옴. 즉 2개가 한번에 나오고 나머지 1개가 나옴,
notification 개수를 5개로 늘려봤더니, 1-1-1-1-1이 나와야 하지만 2-2-1로 나옵니다. 어디가 문제일까요..
 
1. NotificationList
import React from "react";
import Notification from "./Notification";

const reservedNotifications = [
    {
        message: "안녕하세요, 오늘 일정을 알려드립니다.",
    },
    {
        message: "오전은 피곤합니다",
    },
    {
        message: "점심식사 시간입니다.",
    },
    {
        message: "30분 후 잠시 휴식하겠습니다.",
    },
    {
        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);
            }
        }, 5000);
    }

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

export default NotificationList;
 
2. Notification
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;
 
 
도와주세요!

답변 1

6

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

안녕하세요, 권예준님. 소플입니다.

해당 문제는 리액트 버전18에서 Strict Mode의 동작이 변경되었기 때문인 것으로 확인되었습니다.

 

Strict Mode는 개발 모드일 때 잠재적인 버그를 찾을 수 있게 해주는 모드라고 생각하시면 됩니다.

https://reactjs.org/docs/strict-mode.html

 

그리고 리액트 버전18에서 변경된 Strict Mode의 동작과 관련해서는 아래 링크를 참고하시면 좋을 것 같습니다.

https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors

 

위 링크에 나와있는 설명에서 핵심은 "React would unmount and remount trees using the same component state as before." 라는 부분입니다.

즉, 개발 모드에서 Strict Mode를 사용하게 되면, 컴포넌트를 unmount 시켰다가 다시 한 번 remount 시키게 된다는 것입니다.

때문에 저희가 사용했던 componentDidMount() 함수가 두 번 호출이 됩니다.

 

프로덕션 배포를 하게되면 Strict Mode는 무시되기 때문에 정상적으로 작동할텐데,

Strict Mode가 아닌 상태로 테스트를 해보시려면 아래와 같이 하시면 됩니다.

 

index.js 파일에 보시면 아래와 같이 React.StrictMode로 감싸진 부분을 볼 수가 있는데,

해당 부분을 삭제하고 실행해보시면 메시지가 하나씩 추가되는 것을 보실 수 있습니다.

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

 

 

엄격하게 하자면 Strict Mode인 상태에서도 정상적으로 메시지가 1개씩 출력되도록,

아래와 같이 componentWillUnmount() 함수까지 구현을 해야합니다.

componentWillUnmount() {
if (timer) {
clearInterval(timer);
}
}

 

 

다만, 강의는 리액트 버전 17을 기준으로 제작되었고,

Strict Mode까지 다루게 되면 너무 내용이 어려워지기 때문에 예제 코드를 저렇게 작성한 부분에 대해서는 양해 부탁드립니다.

리액트 버전 18을 기준으로 한 코드는 향후에 제공할 수 있도록 하겠습니다.

감사합니다.

권예준님의 프로필 이미지
권예준
질문자

무료 강의인데도 친절하고 자세한 답변 정말 감사드립니다! 

권예준님의 프로필 이미지
권예준

작성한 질문수

질문하기