[React] TypeError: Cannot assign to read only property '0' of object '[object Array]'

박기영·2022년 10월 6일
3

React

목록 보기
16/32
post-thumbnail

제목에 있는 오류에 대한 해결법을 작성하고자 한다.
변경할 수 없는 배열에 대한 변경을 시도했을 경우 발생하는 에러이다.
필자는 TS + Redux Toolkit으로 받아온 데이터를 수정하고자 했고,
useSelector를 활용하여 스토어에서 꺼내온 데이터를 직접 수정하고자 했을 때
이 에러가 발생했다.

문제 상황

필자는 api 통신 결과로 받아온 데이터를 리덕스 스토어에 넣은 뒤,
useSelector로 스토어에서 값을 꺼내왔고,
그 데이터 중, 배열 타입의 데이터를 reverse() 해서 보여주고 싶었다.

데이터가 잘 처리되었는지 console.log()로 확인하고자 아래 코드로 진행했다.

// 스토어에서 데이터 가져오기
const lectureData = useAppSelector((state) => state.lecture.lectureData);

// api 통신으로 받아온 데이터를 스토어에 저장하고
// 그 중, 원하는 특정 데이터(배열)을 가지고 setState 해줌.
useEffect(() => {
  dispatch(loadAllLecture(null))
    .then((res) => {
	  if (res.payload?.lectureList) {
		setLectureList(res.payload.lectureList);
      }
    })
    .catch((err) => console.log(err));
}, []);

// setState의 비동기 처리로 인한 에러를 막기 위해
// useEffect를 사용하여 데이터를 처리해줬다.
useEffect(() => {
  let arr = lectureData.lectureList.reverse();
  console.log(arr);
}, [lectureList]);

가장 아래 부분에 있는 reverse()가 문제의 코드이다.
저 부분을 작성하기 전까지는 아무런 문제가 없다가, 저 코드가 추가된 직후에

참고 이미지

이런 에러가 발생했다.

주목할 점은 read only이다.
읽기 전용 데이터를 필자가 바꾸려고 했기 때문에 에러가 발생한 것이다.

해결 방법은 깊은 복사이다.
쉽게 말해, 변경할 수 없던 데이터를 복사해서 다른 변수에 넣고, 그 값을 수정하는 것이다.

깊은 복사

// 스토어에서 데이터 가져오기
const lectureData = useAppSelector((state) => state.lecture.lectureData);

// api 통신으로 받아온 데이터를 스토어에 저장하고
// 그 중, 원하는 특정 데이터(배열)을 가지고 setState 해줌.
useEffect(() => {
  dispatch(loadAllLecture(null))
    .then((res) => {
	  if (res.payload?.lectureList) {
		setLectureList(res.payload.lectureList);
      }
    })
    .catch((err) => console.log(err));
}, []);

// setState의 비동기 처리로 인한 에러를 막기 위해
// useEffect를 사용하여 데이터를 처리해줬다.
useEffect(() => {
  // 위에서 실행된 useEffect에서 lectureList라는 state를 set했었다.
  // 그 state를 그대로 복사해줬다.(깊은 복사)
  let arr = [...lectureList];

  // 이제 데이터를 수정해도 전혀 에러가 없다!
  arr.reverse();

  setReversedLectureList(arr);
}, [lectureList]);

아까 봤던 코드와 지금 코드의 차이가 뭘까?
스프레드 연산자(Spread Operator) ...을 사용했다는 것이다.

사실 스프레드 연산자가 깊은 복사인지 얕은 복사인지에 대한 말이 사람마다 꽤 다른 것 같은데..
적어도 필자가 알아본 자료들에 의하면 깊은 복사가 맞다는 말이 더 많다.

medium에서 많은 추천을 받은 분의 말을 인용하자면

The spread operator makes deep copies of data if the data is not nested.
- Kevin Lai -

직역하자면 "중첩된 데이터가 아니라면 스프레드 연산자는 깊은 복사가 된다."이다.

이 것에 관련해서는 참고 자료에 링크를 남겨두도록 하겠다.
깊은 복사와 얕은 복사에 대해서도 정확하게 정리해야겠다.

참고 자료

tchaikovsky님 블로그
akjfal님 블로그
Kevin Lai님 블로그

profile
나를 믿는 사람들을, 실망시키지 않도록

0개의 댓글

관련 채용 정보