[spread] 기존 배열에 영향 주지 않고, 추가 / 삭제 /수정

uoayop·2021년 6월 9일
0

React

목록 보기
5/9
post-thumbnail

1️⃣ Users 배열에 유저 추가하기

🚫 배열에 값을 추가할때, 기존 배열에 push로 값을 추가하면 안된다!

💯 기존 배열에 영향을 주지않게끔 새로운 배열을 만들어주고 그 배열에 변화를 주도록 해야한다.

//CreateUser.js

import React from 'react';

// 필요한 컴포넌트를 props 로 받아올 예정
// onchange : input 값이 바뀌게 될 때 호출하는 함수
// onCreate : 버튼을 눌렀을 때 항목을 추가해주는 함수
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;
//App.js
import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function App() {
  // inputs라는 변수에 대해서
  // 초기값 {username:'', email:''},
  // 변경 함수는 setInputs
  const [inputs, setInputs] = useState({
    username:'',
    email:'',
  });
	
  // inputs의 변수를 미리 빼오기
  const {username, email} = inputs;
  // 기존 객체에 영향이 없도록 Spread를 이용
  const onChange = e => {
    const {name,value} = e.target;
    setInputs({
      ...inputs,
      [name] : value
    });
  };

  return (
    <>
      <CreateUser 
        username={username} 
        email={email} 
        onChange={onChange} 
        onCreate={onCreate}/>
      <UserList users={users}/>
    </>
  );
}
//App.js

const [users, setUsers]=  useState([
    {
        id: 1,
        username: 'doyeon',
        email: 'uoayop@kakao.com'
    },
    {
        id: 2,
        username: 'woong',
        email: 'woong@mungmung.com'
    },
    {
        id: 3,
        username: 'woody',
        email: 'andy@friend.com'
    }
  ]);

const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
      // username, email 대신 ...users 가능
    };
    // 새로운 객체 user를 만들어서 값 할당 
    // 기존의 배열 user는 건들이지 않고, user가 추가됨
    
    // 기존 배열 users에 새로 만든 객체 user을 붙여줌
    setUsers(users.concat(user));

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

기존 객체 users에 새로운 객체 user를 더해줄 때

  1. spread 사용
    setUsers([...users, user]);

  2. concat 사용
    setUsers(users.concat(user));


2️⃣ Users 배열에 유저 삭제하기

버튼을 눌렀을 때, 유저가 삭제되게 하려고 한다.
이 때, 주의할 점은 삭제 함수를 지정해줄 때 반드시 화살표 함수로 지정해줘야 한다!

  • 🚫 만약 그냥 deleteFunc() 이렇게 지정해주면 렌더링과 동시에 요소가 삭제되어 버린다.

💯 함수를 호출하는 것이 아니라 함수를 넣어줘야 한다!

//UserList.js

import React from 'react';
import './App.css';

function User({user, onRemove}){
    const {username, email, id } = user;
    return(
        <div>
            <b>{username}</b> 
            <span>({email})</span>
     // 🔥 반드시 화살표 함수로 함수 넣어주기!!!!
            <button onClick={() => onRemove(id)}>삭제</button>
        </div>
    );
}

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

export default UserList;
//App.js

  const onRemove = id => {
    // user.id가 파라미터로 받은 id가 아닌 경우에만 
    // 새 리스트로 묶어서 반환해준다.
    // 반환된 리스트를 setUsers로 업데이트 해준다.
    setUsers(users.filter(user => user.id !== id))
  }

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

3️⃣ Users 배열에 유저 삭제하기

map 함수를 사용하면, 쉽게 배열의 요소를 수정할 수 있다.

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

매개변수로 받은 id를 갖는 user를 찾아서
active 변수의 상태를 토글해준다.

이 때, 위의 경우와 마찬가지로 기존의 user 요소를 그대로 들고오고 ...user,
바뀐 값만 덮어씌워주는 형태로 수정해준다.


정리

  • 배열의 특정 값을 수정할 땐, 기존의 배열에 영향이 가지 않도록, spread를 사용한다.

    setState([...기존 배열, 새로 추가된 내용])

  • 배열 각각의 요소에 접근할 땐 map 함수를 사용하면 편하다.

  • map 함수
    map 함수엔 아이템의 고유값을 key 값으로 함께 넣어주는 것이 권장된다.

users.map(
    (user,index) 
    => (<User user={user} key={index} />),
)

key 값이 있어야만 렌더링 한 결과물이 어떤 객체를 가리키고 있는지 정확하게 알게된다.
그래야만 조금 더 빠르고 효율적으로 동작하게 된다.

profile
slow and steady wins the race 🐢

0개의 댓글