리액트에서 state가 불변성을 유지해야하는 이유?

김철준·2023년 3월 11일
1

REACT

목록 보기
28/33

리액트에서 state에서는 불변성을 유지해야한다는 말은 많이 들어보셨을 것입니다.

그렇다면 불변성이라는 성질은 무슨 말이고 이를 유지한다는 것은 어떤 의미일까?

불변성과 불변성 유지

불변성이란 불(아닐 불) 변(변할 변)으로써 변하지 않는 성질을 말합니다.

그러면 무엇이 변하지 않으면 될까요?

할당한 값이 변하지 않으면 됩니다.

즉, 불변성을 유지해야한다는 말은 초기에 할당한 값 자체를 변경하면 안된다는 것입니다.

useState(초기값)에서 초기값을 setState가 아닌 방법으로 변경하면 안된다는 것이죠.

다음을 자세히 살펴봅시다.

state가 불변성을 유지하지 않는다면?

그러면 리액트에서 state가 불변성을 유지하지않으면 어떻게 될까요?

state가 불변성을 유지하지 않는다라는 것은 setState로 state값을 할당하는 것이 아닌 state 자체 값을 변경한다는 것입니다.

예를 들어 , useState에서 초기값을 외부의 배열을 할당한다고 해봅시다.

const arr = [1,2,3]
const [value,setValue] = useState(arr)

value.push(4)
// value.concat(4)
setState(value)

위 예시는 arr이라는 배열은 useState의 초깃값으로 할당하고 setState로 state 값을 할당해주는 것이 아닌 state 자체에 접근하여 값을 변경해주고 있습니다.

이렇게 state를 직접 수정한다면 리액트는 state 값이 변경되었다는 것을 감지하지 못할 수 있습니다.

이유는 state를 직접 수정하면 React는 이전 state와 새로운 state를 비교할 때 참조 비교(reference comparison)를 사용하기 때문입니다.

참조 비교를 한다는 것은 두개의 객체를 비교한다는 것인데 이전 state와 값을 변경하는 state는 어쨋든 같은 객체 참조 주소를 가지고 있습니다.

때문에 리액트에서는 같은 값으로 인식하고 변화 값을 반영해주지 않는 것입니다.

그렇다면 불변성을 유지하려면 어떻게 해야할까?

그렇다면 위 예시에서 불변성을 유지하려면 어떻게 해야할까요?
setState 함수를 활용하면 인수로 새로운 값을 할당하기 때문에 이전 객체와는 다른 참조 주소를 가지고 있습니다.

때문에 리액트는 이전 state와 새로운 state를 다른 참조 주소로 인식하여 변화된 값을 올바르게 변경해줍니다.

다음은 setState를 활용하여 state 불변성을 유지하며 state 값을 변경해주는 예시입니다.


const arr = [1,2,3]
const [value,setValue] = useState(arr)

setValue([...value,4])

...(스프레드 연산자)를 사용하면 해당 배열의 값을 꺼내어 새로운 배열의 값으로 할당해줄 수 있습니다.

때문에 새로운 배열에 이전 state값을 꺼내고 추가로 할당하고 싶은 값을 넣어주어 새로운 배열을 할당해주면 불변성을 유지하여 값을 변화를 감지하게 할 수 있습니다.

즉, state가 불변성을 유지하기 위해서는 항상 새로운 객체를 생성하고 이전 state 값을 복사한 후 변경된 값을 setState의 인수로 할당해야합니다.

객체를 복사하는 법

  • Object.assign()
  • ...(스프레드 문법)

배열을 복사하는 법

  • slice()
  • ...(스프레드 문법)
profile
FE DEVELOPER

0개의 댓글