Trouble Shooting

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

봄나물소년 2024. 2. 27. 10:27

filter를 이용해 최신순, 오래된순, 좋아요순으로 불러온 게시물들을 filtering 하는 기능을 구현하다가

위와 같은 에러를 보았다.

확인해보니 오래된순으로 filtering하기 위해 원본데이터.reverse()를 한 부분에서 났다고 한다.

해석해보면 "read only 데이터에 할당할 수 없다."이다.

 

mdn에서 array.reverse() 에 대해서 찾아보았다.

reverse() 메소드는 원본배열을 destructing한다.

즉 원본을 바꿔버리는 것이다.

 

그러니 원본 배열을 mutating 하지않고 reverse시키는 방법을 찾으면 될 것 같다.

깊은복사하는 방법으로 에러를 해결해보자.

 


 

해결1

깊은복사

export const filteredPostListState = selector({
  key: 'filteredPostListState',
  get: ({get}) => {
    const filter = get(filterTypeState);
    const list = get(postListState).list;
    
    switch (filter) {
      case 'latest':
        return list
      case 'out-of-date':
        const newList = [...list]; // 배열 복사
        return newList.reverse()
      case 'likes':
        return list
      default:
        return list;
        }
      },
    });

... spread operator 를 이용하여 deep copy 하는 방법을 썼다.

iterable한 value를 쉽게 deep copy할 수 있는 방법이다.

배열이나 객체를 setState로 업데이트할 때 자주 사용하는 방법이기도하다.

deep copy한뒤 업데이트를 해야 새로운 값이 원본과 다른 참조를 가리켜 리액트가 업데이트를 알아차릴 수 있기때문이다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

 

Spread syntax (...) - JavaScript | MDN

The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the propert

developer.mozilla.org

 

해결2

array.toReversed()

 

MDC에서 reverse()를 좀 뒤적여보다가 

toReversed()를 사용하면 mutating 없이 원본 배열을 뒤집을 수 있다고한다.

처음보는 메서드라 링크를 들어가보았다.

뒤집어진 새로운 배열을 반환한다고 한다.

신기하군~

case 'out-of-date':
	return list.toReversed();