Front-End/React

[React] 배열에 항목 추가, 제거, 수정

LightSource 2022. 9. 20. 11:12

이 글은 velopert님의 벨로퍼트와 함께하는 모던 리액트를 참고하여 쓴 글 입니다.

https://react.vlpt.us/

 

벨로퍼트와 함께하는 모던 리액트 · GitBook

벨로퍼트와 함께하는 모던 리액트 본 강의자료는 패스트캠퍼스 온라인 강의에서 제공하는 리액트 강의에서 사용되는 강의 문서입니다. 이 튜토리얼은 여러분들이 JavaScript 의 기초를 잘 알고있

react.vlpt.us

배열에 요소 추가하기

배열에 항목을 추가한다는 것은 변화를 주는 것이기 때문에 리액트에서의 불변성을 지켜주어야 한다.

따라서 useState에 등록된 setter에서 변화를 줄때, 배열의 push, splice, sort 등의 함수는 사용할 수 없다.

불변성을 지키면서 배열에 항목을 추가하는 방법 2가지

  1. spread연산자를 사용하는 방법
  2. concat 함수를 사용하는 방법

 

CreateUser.js 생성

import React from 'react';

function CreateUser({ username, email, onChange, onCreate }) {
  return (
    <div>
      <input
        name="username"
        placeholder="계정명"
        onChange={onChange}
        value={username}
      />
      <input
        name="email"
        placeholder="이메일"
        onChange={onChange}
        value={email}
      />
      <button onClick={onCreate}>등록</button>
    </div>
  );
}

export default CreateUser;

1. spread 연산자를 사용하는 방법

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;

  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers([...users, user]);  //전개 연산자를 이용해서 새로운 배열을 생성

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} />
    </>
  );
}

export default App;

2. concat함수를 이용하는 방법

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));  // concat함수를 이용해서 불변성을 지킴

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} />
    </>
  );
}

export default App;

배열에 새 항목을 추가 할 때에는 spread 연산자를 사용하거나, concat 함수를 사용하면 된다.

배열에서 요소 삭제하기

삭제 버튼 렌더링

  • 배열에 항목을 제거하기 위해 먼저 User 컴포넌트에서 삭제 버튼을 렌더링해준다.
  • 또한 후에 추가할 삭제하는 기능을 가진 onRemove함수를 props로 전달 받는다.

 

UserList.js

import React from 'react';

function User({ user, onRemove }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
      <button onClick={() => onRemove(user.id)}>삭제</button> // 삭제 버튼 생성
    </div>
  );
}

function UserList({ users, onRemove }) {
  return (
    <div>
      {users.map(user => (
        <User user={user} key={user.id} onRemove={onRemove} />  // User컴포넌트로 삭제함수 전달
      ))}
    </div>
  );
}

export default UserList;

삭제 버튼에 부여해줄 로직 설정

삭제 버튼이 클릭 될때, user.id 값을 onRemove함수의 파라미터로 받아와서 호출해 줘야 한다.

onRemove는 id가 user.id와 일치하는 객체를 삭제하는 역할을 가진다.

onRemove함수는 App.js에서 UserList 컴포넌트로 전달되며, 그대로 User컴포넌트에도 전달이 된다.

 

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = id => {  // onRemove 함수 생성
    // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
    // = user.id 가 id 인 것을 제거함
    setUsers(users.filter(user => user.id !== id));
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} /> // onRemove함수 UserList로 전달
    </>
  );
}

export default App;

배열에서 요소 수정하기

User 컴포넌트에서 계정명을 클릭했을때 색상이 초록색으로 바뀌고, 다시 누르면 검정색으로 바뀌도록 구현

색상을 표현하는 기준이 될 active 속성을 users 객체에 추가해준다.

수정할 요소를 users 객체에 추가

 

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com',
      active: true    // active 속성 추가 
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com',
      active: false   // active 속성 추가 
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com',
      active: false   // active 속성 추가 
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = id => {
    // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
    // = user.id 가 id 인 것을 제거함
    setUsers(users.filter(user => user.id !== id));
  };

  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
    </>
  );
}

export default App;

추가한 속성의 값에 따라 색상이 바뀌도록 구현

추가한 active의 값에 따라서 user.name을 표현하는 태그의 style 속성을 변경시켜 준다.

 

UserList.js

import React from 'react';

function User({ user, onRemove }) {
  return (
    <div>
      <b
        style={{
          cursor: 'pointer',  // 마우스를 올렷을때 커서가 손가락 모양으로 바뀜
          color: user.active ? 'green' : 'black'  // active 값에 따라 color 스타일 지정
        }}
      >
        {user.username}
      </b>

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

function UserList({ users, onRemove }) {
  return (
    <div>
      {users.map(user => (
        <User user={user} key={user.id} onRemove={onRemove} />
      ))}
    </div>
  );
}

export default UserList;

기본값이 true인 요소가 초록색으로 나타난다.

클릭시 색이 변하는 기능 구현

  • 클릭시 발생하는 onToggle 함수를 생성해서 id 값을 비교해 같은 값이면 active값을 반전시키도록 구현

 

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  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
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = id => {
    setUsers(users.filter(user => user.id !== id));
  };
  const onToggle = id => {   // onToggle함수 생성
    setUsers(
      users.map(user =>      // map함수를 이용해서 user.id와 파라미터의 id를 비교
        user.id === id ? { ...user, active: !user.active } : user  // 같은 값이면 active값을 반전
      )
    );
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} /> {//onToggle함수 UserList컴포넌트로 전달}
    </>
  );
}

export default App;

UserList에서 전달받은 onToggle 함수를 User 컴포넌트에 전달해주고, 해당 함수를 user.username이 보여지는 태그에 등록

 

UserList.js

import React from 'react';

function User({ user, onRemove, onToggle }) {
  return (
    <div>
      <b
        style={{
          cursor: 'pointer',
          color: user.active ? 'green' : 'black'
        }}
        onClick={() => onToggle(user.id)}
      >
        {user.username}
      </b>
      <span>({user.email})</span>
      <button onClick={() => onRemove(user.id)}>삭제</button>
    </div>
  );
}

function UserList({ users, onRemove, onToggle }) {
  return (
    <div>
      {users.map(user => (
        <User
          user={user}
          key={user.id}
          onRemove={onRemove}
          onToggle={onToggle}
        />
      ))}
    </div>
  );
}

export default UserList;

계정명을 눌러서 색이 바뀌는지 확인 해보기

정리

배열에 요소 추가

  • useState의 setter에서 리액트의 불변성을 지키면서 해당 요소를 추가할것
  • Spread연산자 사용하는 방법
setUsers([...users, user]);
  • concat함수 사용하는 방법
setUsers(users.concat(user));

배열 요소 삭제

  • filter를 통해서 조건을 만족하는 값 추출
  const onRemove = id => {
    setUsers(users.filter(user => user.id !== id));
  };
  • 태그에서 변수를 전달할때는 화살표 함수를 통해서 전달
<button onClick={() => onRemove(param)}>

배열 요소 수정

  • 배열의 불변성을 유지하면서 업데이트 할 때에도 map함수를 사용
const onToggle = id => {   // onToggle함수 생성
    setUsers(
      users.map(user =>      // map함수를 이용해서 user.id와 파라미터의 id를 비교
        user.id === id ? { ...user, active: !user.active } : user  // 같은 값이면 active값을 반전
      )
    );
  };

 


참고글

https://react.vlpt.us/basic/15-array-modify.html

 

15. 배열에 항목 수정하기 · GitBook

배열 항목 수정하기 이번에는, 배열 항목을 수정하는 방법을 알아보겠습니다. User 컴포넌트에 계정명을 클릭했을때 색상이 초록새으로 바뀌고, 다시 누르면 검정색으로 바뀌도록 구현을 해봅시

react.vlpt.us

 

반응형