본문 바로가기
Coding/REACT

[React] setState를 해도 렌더링이 안되는 이유

by 하상원이야 2022. 9. 26.

안녕하신가 ?

 

오늘(일요일)은 회사 앱에 추가될 기능을 연습하기 위해 Google Form을 클론 코딩하고 있었다.

대충 이렇게 생김

 

위 프로그램을 코딩하면서, 질문을 여러 개 만들었다가 삭제하는 기능을 만들었다.

 

딜리트. 말 그대로 추가한 걸 삭제하는 기능인데, 실행되는 index를 받아서 해당 배열에서 그 Index를 지우는 거다.

 

대충 이런 기능

 

문제 없이 생긴 기능. 허나 전혀 작동하지 않는다.

 

정확하게 말하면 setState로 인해 state 값이 변경되었는데도, 화면이 리렌더링 되지 않는다.

 

뭐야 !?

 

그래서 일단 다른 스테이트를 선언해서 setSurveyList 밑에 setCount(count+1) 막 이렇게 선언해봤다.

 

그러면 렌더링 된다. shit, 대체 뭐지하고 구글링 해보니 내 멍청함을 알게 되었다.

 

setState를 해도 렌더링이 안되는 이유

 

React 내부적으로, State가 변경되었을 때 얕은 복사를 사용해 비교하고, 페이지를 렌더링할지 정한다.

 

즉 ! State가 어디를 참조하고 있는지만 비교할 뿐이다.

 

참조하고 있는 곳의 값, 나의 경우 배열 안의 값비교되지 않은 것이다.

 

그 약간 포인터 개념의 가르키는 곳은 그대로고 그 안에 값만 바뀌어서 그런 것 같다.

 

리액트의 불변성

근데 리액트에서는 불변성을 지켜줘야 한다.

( 지나치게 많은 연산을 피하기 위해 )

여기서 불변성이란 변하지 않는 것을 뜻하는데, 한 번 메모리에 어떤 값이 저장되면 그 값을 안바꾼다는 얘기다.

let a = 1; 
a = 2;

1이라는 데이터를 저장해놓고,

a를 2로 재할당 했을 때, 1을 바꾸는 것이 아니라,

새로운 곳에 2를 만들고 a를 그 곳을 가르키게 하는 것이다!

 

불변성의 진정한 의미는 메모리 영역에서 값을 변경할 수 없다! 는 의미이다.

 

그렇다면 불변성을 지키는 방법
array.push('새로운 값');

-> 이런 방법은 배열에 그대로 값을 추가하기 때문에 불변성을 지켜주지 않는다. 

 

불변성을 지키기 위해서는 spread operator, map, filter, slice, reduce 등등 새로운 배열을 반환하는 메소드들을 활용하면 된다.

* splice는 원본데이터를 변경함

 

아주 보기 좋게 난 저기 splice를 써놨다 ㅎㅎ; 

 

렌더링 해결

spread operator 사용

이렇게 마지막에 spread operator만 사용해도 해결된다 !

spread operator는 배열을 해체했다가 다시 재구성한다고 한다

원래 surveyList가 가르키고 있던 곳의 데이터를 바꾸는게 아닌 새로운 곳에 내가 만든 newArr의 데이터를 저장하게 되는 것이다 !

 

알겠나 ?.. In React, must be immutability.

 

참고 -

https://hsp0418.tistory.com/171

https://blog.logrocket.com/immutability-in-react-ebe55253a1cc/

반응형

댓글