리액트 React 배열 항목 추가, 제거, 수정하기 (불변성 지키며)

라용·2022년 11월 4일
1

벨로퍼트 모던 리액트 내용을 일부 정리했습니다. (아래는 생략된 코드가 많으니 자세한 것은 원문 링크를 참고하세요)

리액트에서 배열을 컴포넌트의 상태로서 관리할 수 있습니다. 초기 세팅은 아래처럼 useState 로 선언을 하고 초기값에 배열을 담아 둡니다.

const [users, setUsers] = useState([
  {
    id: 1,
    username: 'velopert',
    email: 'public.velopert@gmail.com',
    active: true,
  },
  {
    id: 2,
    username: 'tester',
    email: 'tester@example.com',
    active: false,
  },
  {
    id: 3,
    username: 'liz',
    email: 'liz@example.com',
    active: false,
  },
]);

위 배열에 변화를 줄 때는 객체와 마찬가지로 불변성을 지켜주어야 합니다. 배열의 push, splice, sort 등을 사용하면 안되고, 사용하더라도 기존의 배열을 복사한 후 써야 합니다. 불변성을 지키며 배열에 새 항목을 추가하는 방법은 spread 연산자를 쓰거나 concat 함수를 사용하는 방법 두가지 입니다. (concat 함수는 기존 배열 수정하지 않고, 새로운 원소 추가한 새 배열 만듬)

// spread 연산자

const onCreate = () => {
  const user = { // 사용자가 새로 입력한 값 담고
    id: nextId.current,
    username,
    email,
  };
  setUsers([...users, user]); // 여기서 기존 배열에 넣기
};

// concat 함수

const onCreate = () => {
  const user = {
    id: nextId.current,
    username,
    email,
  };
  setUsers(users.concat(user)); // 여기서 사용
};

배열의 특정 항목을 지우고 싶다면, 삭제 버튼에 콜백 함수로(삭제 함수를 프롭스로 전달 받는다면) 해당 값의 id 값을 파라미터로 담아 전달해야 합니다.

<button onClick={() => onRemove(user.id)}>삭제</button>

이렇게 전달한 값을 불변성을 지키며 업데이트하려면 filter 함수를 사용해야 합니다. (배열에서 특정 조건을 만족하는 원소들만 추출해 새로운 배열 생성)

const onRemove = id => {
  setUsers(users.filter(user => user.id !== id));
};

// setUsers 로 배열을 바꾸어 주는데 선택한 것의 user.id 가 기조 id 와 다른 것들만 답는다. 같은 것, 선택한 것은 제외하고 담는다.

이제 배열 항목을 수정해보겠습니다. 배열안에 active 값에 따라 폰트 색상이 바뀌도록 아래 처럼 세팅하고,

<b
  style={{
    cursor: 'pointer',
    color: user.active ? 'green' : 'black',
  }}
>
  {user.username}
</b>

onToggle 함수를 만들어서 수정합니다. 이때도 배열의 불변성을 고려해 map 함수를 사용할 수 있는데, id 값을 비교해서 id 가 다르면 그대로 두고, 같다면 active 값을 반전시키도록 합니다. 선택한 요소의 id 값을 콜백함수의 파라미터로 전달하는 방식은 위 제거하기와 유사합니다. onToggle 함수를 아래와 같이 작성하고,

const onToggle = id => {
  setUsers(
    users.map(user =>
      user.id === id ? { ...user, active: !user.active } : user
    )
  );
};

onClick 이벤트에 onToggle 함수를 넣어줍니다.

<b
  style={{
    cursor: 'pointer',
    color: user.active ? 'green' : 'black',
  }}
  onClick={() => onToggle(user.id)}
>
  {user.username}
</b>
profile
Today I Learned

0개의 댓글