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

학생1님의 프로필 이미지
학생1

작성한 질문수

처음 만난 리액트(React)

(실습) state 사용하기

state.notifications 배열에 push가 가능한지 질문드리겠습니다.

작성

·

351

0

const { notifications } = this.state;
const index = notifications.length;
notifications.push(reservedNotifications[index]);
this.setState({
    notifications: notifications
})

위 코드에서 state.notifications 배열에 바로 push를 해서 setState를 해줬는데

지난 강의에서는 state에 있는 배열 또는 객체를 직접 수정하지 않고 복사해서

newNotifications = [...notifications] 처럼

새로 할당 한 다음 setState를 해준다고 봤던 부분이 있어서

어떤 경우에는 직접 state배열에 push가 가능한지 질문 드려도 괜찮을까요

 

강의 잘 보고 있습니다. 감사합니다!

답변 1

0

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

안녕하세요, 소플입니다.

setState() 함수를 호출할 때,

기존 state 값에 어떤 변화를 준 뒤에 그 값을 넣어 호출하면 state에 새로운 값이 들어가게 됩니다.

하지만 state 값에 변화를 주기만 하고 setState()로 값을 업데이트 해주지 않으면,

재렌더링이 일어나지 않기 때문에 새로운 값이 화면에 나타나지 않게 됩니다.

그래서 리액트 컴포넌트의 라이프사이클에 맞춰서 데이터를 관리하기 위해서 state를 직접 수정하면 안 된다고 하는 것입니다.

 

notifications 배열의 경우 기존 배열에 아이템을 추가/삭제 한 뒤에,

setState() 함수를 호출해서 새로운 값을 state에 업데이트 하게 됩니다.

이 과정에서 기존 state를 수정하고 그 값을 넣게 되는데,

일반적인 경우에서는 이렇게 해도 정상적으로 작동합니다.

하지만 setState()가 짧은 시간 내에 동시 다발적으로 불리는 경우에는 이렇게 코드를 짜게 되면 오작동이 일어날 수 있습니다.

그래서 정확하게 기존 state로부터 값을 업데이트 하기 위해서는,

이전 state로부터 새로운 state를 생성해서 업데이트 해야 합니다.

참고로 기존 값을 수정하지 않고 새로운 값을 만들어서 업데이트하는 이러한 방식을 Immutable Update라고 하며,

리액트에서는 아래와 같은 형태로 사용합니다.

// Counter 예시

// Class Component
this.setState((prevState) => {
    return {
        ...prevState,
        count: prevState.count + 1,
    };
});

// Function Component
setCount((prevCount) => {
    return prevCount + 1;
});

예상치 못한 동작을 막기 위해서는 코드의 양이 조금 많아질 수는 있지만,

확실하게 기존 state로부터 값을 업데이트 하는 것이 좋습니다.

 

강의에서는 두 가지 방식이 다 등장한다고 보시면 되고,

관련해서 더 자세한 내용은 아래 링크를 참고하시면 좋을 것 같습니다!
https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state

감사합니다.

학생1님의 프로필 이미지
학생1

작성한 질문수

질문하기