react의 state가 객체(배열)라면..?(feat. 변수)

이승훈·2022년 9월 3일
1

TIL

목록 보기
1/31
post-thumbnail

들어가기전에

리액트는 state의 변화를 감지하여 컴포넌트를 리렌더링한다.
setState(newState)를 통해 state를 변경할 때 리엑트는 새로받은 newState와 기존의 state값을 비교하여 그 둘이 다르다면 새로 받은 newState를 반영하여 컴포넌트를 리렌더링한다.

변수에 관하여

state또한 변수다.
변수는 임의의 값을 저장한 메모리 주소에 대응한다.
메모리 안의 각 셀들은 고유의 주소를 갖는다.
(예를들어 4GB 메모리는 2^32개수의 셀주소를 가지게 된다. 각 셀1개는 1바이트(2^4 비트)의 크기를 가지고있다.)

즉, 변수의 정의는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이며 이 변수를 통해 데이터에 재접근이 용이해지는 것이다.

간단히 말하자면 변수는 프로그래밍 언어에서 값을 저장하고 참조하는 메커니즘으로, 값의 위치를 가리키는 상직정인 이름이다.

변수의 할당과 재할당

우리가 변수를 선언하고 할당하고 그것을 또 재할당할 때 변수는 새로이 할당되는 값을 가지고있는 메모리주소를 참조한다.
즉, 참조하는 메모리주소값을 바꾸는 것이다.

하지만 이것은 원시타입의 데이터에만 해당한다.
객체(배열)타입의 데이터를 참조하는 변수를 수정하면 새로운 객체를 만들어 수정된 객체를 새로운 메모리에 저장한 뒤 새로 저장된 객체의 주소를 참조하지 않는다.

기존의 객체를 수정한다.
당연하게도 그 객체를 참조하는 변수가 가지고있는 메모리주소도 그대로다.

state가 객체,배열 이라면?

글의 서두에서 적어놓았듯 리액트는 state가 가진 값이 변경되면 컴포넌트를 리렌더링한다.

state또한 변수이고 그 값이 원시값이라면 setState() 함수안에 새로운 값을 넣어주었을 때 state가 참조하는 메모리 주소가 변경되니 나의 의도에 부합하게 동작한다.

하지만 만일 state가 객체,배열이라면 원시타입과 동일하게 state를 수정해주면 안된다.
왜냐하면 수정해주어도 state는 그 내용이 변경된 배열을 그대로 참조하기 때문이다.
새로운 메모리주소를 참조하는게 아닌 기존의 메모리주소를 그대로 참조하고 있기 때문에 리액트는 state가 변경되었다 판단하지 못하고 나의 의도대로 컴포넌트를 리렌더링 하지 않는다.

state가 객체,배열 일 때 수정하는 방법

새로운 객체(배열)데이터를 만들어준다.
-> 새로운 메모리공간에 데이터를 할당한다는 의미
setState() 함수를 사용해 새로 만들어준 배열을 입력해준다.
-> state가 새로운 메모리주소를 참조하게 해준다는 의미

이 때 spread 문법을 사용하면 편리하게 새로운 객체(배열)을 만들어 할당이 가능하다.
(아래의 예시 참고)

const [arr, setArr] = useState(['a', 'b', 'c', 'd'])

let newArr = [...arr]
newArr[0] = 'e'
setArr(newArr)

console.log(arr) // ['e', 'b', 'c', 'd']
profile
Beyond the wall

1개의 댓글

comment-user-thumbnail
2023년 1월 23일

감사합니다. 문제 해결했습니다. React 공부하는데 처음으로 전공지식이 활용되는것 같네요.

답글 달기