[고찰] React에서 배열 요소 삭제시 배열을 복사해야 하는 이유에 대한 고찰

react에서 배열 자료를 다룰 때에는 copy본을 만드는게 좋다.

처음 배울 때에는 원본 배열을 남겨놓는게 좋으니 그러는가보다 하며 넘겼는데, 방금 겪어보니 이유를 알겠다.

 

아래가 내가 해결해야 했던 문제다.

react에서는 state함수를 사용하여 변수를 다루는데, 아래처럼 const [tags, setTags]=useState(어쩌구) 일 때, setTags()를 이용해야 tags를 변경할 수 있다.

//tags 배열
const [tags, setTags] = useState(['a', 'b']);

//indexToRemove로 삭제할 인덱스 받음
const removeTags = (indexToRemove) => {

    //태그를 삭제하는 메소드 작성
    
    
};

 

그런데 문제는 setTags()를 이용해 배열의 요소를 삭제하려고 하니 .splice()를 써야겠는데 문제는 .splice()는 삭제하고 난 후 남은 배열이 아니라 '삭제한 요소'를 배열로 갖는다.

//예시
let arr = [1, 2, 3]

let a = arr.splice(0, 1) //[1]

console.log(a) //[1]
console.log(arr) //[2, 3]

 

먼저 삭제하고 남은 배열을 setTags()의 괄호 안에 넣고싶어도 애초에 삭제를 setTags()로 해야 해서 setTags() 안에 splice를 넣으면 삭제 후 남은 배열이 아닌 삭제해야할 배열에 tags에 들어가버리고, setTags()를 안 쓰고 배열을 삭제하자니 방법이 없다.

 

그래서 아래처럼 카피본을 만들어 splice를 한 후 setTags에 카피본을 넣어주면 문제를 해결할 수 있다.

 

//tags 배열
const [tags, setTags] = useState(['a', 'b']);

//indexToRemove로 삭제할 인덱스 받음
const removeTags = (indexToRemove) => {

    //태그를 삭제하는 메소드
    let copy = [...tags];
    copy.splice(indexToRemove, 1)
    setTags(copy);
    
};

 

그럼 처음부터 useState가 아닌 일반 변수를 사용하면 되지 않나?

 useState는 변수에 변화가 생길 때 마다 html을 다시 렌더링해준다. 사용자가 무언가를 입력하면 입력내용이 배열에 삽입되면서 변수에 변화가 생기니까 즉각 변화를 반영해 화면에 띄워주는것이다. 위에서도 카피본을 잠깐 만든 것은 렌더링이 필요 없지만 카피본에서 필요한 요소를 삭제 후 useState인 tags에 삽입하면서 사용자에게 보여지게 된다. 때문에 리엑트에서 변화시 렌더링이 필요한 변수를 일반 변수로 사용하게 되면 제대로 작동하지 않는 모습을 볼 수 있다.

'Diary > 과제, 고찰' 카테고리의 다른 글

[과제] react custom component  (1) 2023.04.20
[과제] mini node server  (0) 2023.04.04
[고찰] 권토중래(捲土重來)  (0) 2023.03.26