본문 바로가기

리액트

[react] 리액트에서 상태에 대한 정리(3) - 배열

반응형

 

-  리액트 공식 문서 기반으로 이해한 내용을 정리한 포스트 입니다. -

 

 

리액트에서 배열의 상태 또한 읽기 전용으로 취급한다.

자바스크립트에서 배열은 직접 변경이 가능하지만, 리액트에서 state 로 취급될 때에는 변경이 불가능한 것으로 취급해야 한다. 즉, 객체와 마찬가지로 상태의 복사본을 만든 후 , 새 배열이 기존 상태를 대체하도록 해야한다.

 

예를 들어, array[1] = 5 와 같이 배열의 요소에 값을 직접 변경하거나, push(),  pop(),  splice() 와 같이 원본 배열의 상태를 직접적으로 변경하는 일체의 행위는 리액트에서는 불가능한 것으로 취급해야 한다.

 

이는 반대로, map(), slice(), filter() 와 같이 원본 배열의 상태를 변경시키지 않고, 새로운 배열을 생성하는 메서드는 사용해도 된다는 것을 의미한다.

 

리액트에서 배열에 새로운 값을 추가하려면 

리액트에서는 원본 배열을 변경시키는 것은 금지한다고 했다. 그렇다면 원본 배열을 변경시키지 않고, 배열에 새로운 값을 추가하려면 어떻게 해야 할까? 이럴 때 ... 이라는 배열 전개 구문을 사용하면 된다.

 

예를 들어, let a =[1,2,3] 이라는 배열이 존재할 때, let b = [...a] 과 같이 배열전개구문을 사용하면 a 라는 변수의 배열과는 다른 새로운 배열 이지만 출력을 해보면 a 와 b 모두 [1,2,3] 이라는 요소를 동일하게 가지고 있다. 하지만 메모리 공간 상에는 서로 다른 주소에 저장되므로 a === b 로 비교해보면 false 가 나오는 것을 확인할 수 있다.

  const a = [1,2,3]
  const b = [...a]
  
  console.log(a === b) // false

 

 

전개 연산자의 이러한 특성을 이용해서 리액트에서 새로운 값을 배열에 추가하려면, 다음과 같이 활용할 수 있다.

- unshift() 메서드와 같이 동작하는 방식

import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);
  return (

     <>
	  <input
        value={name}
        onChange={e => setName(e.target.value)}
      />	
      <button onClick={() => {
        setArtists([
         ...artists, // --> 기존 배열에서 [ ] 을 제거 후 요소를 a,b,c 와 같이 펼침
         { id: nextId++, name: name }
        ]);
      }}>Add</button>
    </>
      
  );
}

 

- push() 메서드와 같이 동작하는 방식

import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);
  return (
     <>
	  <input
        value={name}
        onChange={e => setName(e.target.value)}
      />	
      <button onClick={() => {
        setArtists([
         { id: nextId++, name: name },
         ...artists // --> 기존 배열에서 [ ] 을 제거 후 요소를 a,b,c 와 같이 펼침
        ]);
      }}>Add</button>
    </>
      
  );
}

 

리액트에서 배열의 요소를 제거하려면

배열에서 특정 요소를 제거하려면 기존 배열에서 조건과 일치하는 경우만 새로운 배열로 반환하는 filter() 메서드를 활용할 수 있다.  

 

아래의 예시대로라면 기존 배열의 id 와 클릭이벤트가 등록되어 있는 요소의 id 가 일치하지 않는 경우만 true 로 취급하여 새로운 배열로 반환하기 때문에 결과적으로 본다면 배열의 요소가 삭제된 새로운 상태가 리렌더링 되면서 기존 상태를 대체하게 된다.

 <ul>
        {artists.map(artist => (
          <li key={artist.id}>
            {artist.name}{' '}
            <button onClick={() => {
              setArtists(
                artists.filter(a =>
                  a.id !== artist.id
                )
              );
            }}>
              Delete
            </button>
          </li>
        ))}
</ul>

 

반응형