카테고리 없음

[react] 배열에 항목 추가 / 배열에 항목 제거

문앵 2022. 1. 25. 16:38

 

 

 

 

https://react.vlpt.us/basic/13-array-insert.html

 

13. 배열에 항목 추가하기 · GitBook

13. 배열에 항목 추가하기 이 섹션에서 사용된 코드는 다음 페이지에서 확인 할 수 있습니다. 이번에는 배열에 새로운 항목을 추가하는 방법을 알아보겠습니다. 우선, input 두개와 button 하나로 이

react.vlpt.us

 

(기존에 쓰던 코드에 이어서)

 

지금까지 구현된 기능과 컴포넌트 구조를 정리해보자면,

 

이름, 닉네임을 적을 수 있는 input이 각각 하나씩 있고 등록 버튼이 있다.

그 아래에 3명의 유저 이름과 닉네임이 적혀있고,

내가 input에 이름과 닉네임을 적어서 등록버튼을 누르면 그 밑에 차례대로 해당 이름과 닉네임이 적힌다.

 

쉽게 말해 유저 등록 명부 같은 것을 만든셈이다.

이런식으로 이름과 닉네임이 등록된다

 

 

 

 

컴포넌트 구조

 

구조를 살펴보면,

우선 파일 트리는 

App.js > CreateUser.js , UserList.js 

App 에서는 상태를 생성하거나, 이것을 관리해주는 함수가 들어있다. 

CreateUser에는 입력을 받는 input과 등록버튼 이 있는 컴포넌트가 들어있다.

UserList에는 생성된 항목 (유저의 이름과 닉네임)을 보여주는 컴포넌트가 들어있다.

컴포넌트 구성

 

 

이 프로세스가 어떤 원리로 이뤄져 있는가?

 

1. App 컴포넌트

- app 컴포에는 필요한 상태를 만들고 이 상태를 하위 컴포에 props로 전달하여 사용.

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:'csprout@nate.com'
  },
  {
      id:2,
      username:'tester',
      email:'test@test.com'
  },
  {
      id:3,
      username:'tester2',
      email:'test2@test.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. CreateUser 컴포넌트

input 박스 2개, button 1개로 구성

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;

 

 

 

3. UserList

등록된 유저의 정보가 보이는 곳. 

User라는 컴포넌트를 하위에 따로 만들어서 재사용할 수 있도록 만들어줬다.

또한 map을 이용해서 배열의 값을 렌더링 되게 해줬다.

import React from 'react';

function User({ user }){
    return (
        <div>
            <b>{user.username}</b> <span>({user.email})</span>
        </div>
    );
}

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



export default UserList;

 


 

코드를 작성하고 나서도 어떤 원리로 동작되는건지 완벽하게 이해하고 싶었기 때문에 수기로 정리한 내용을 작성하려고 한다.

이 부분은 공부할때 재참고하기엔 부적절할 수 있음. 정리용임

 

1. inputbox에 내용 입력하면 입력한 값이 실시간으로 밑에 나타나고

초기화버튼을 누르면 입력된 내용이 초기화되고 포커스가 특정 input으로 가게되는 기능.

-

사용한 hooks = 포커스 -useRef() , input - useState({})이용해서 객체형태의 상태 만들기

바뀌는 값을 그대로 보여주려면 onChange가 있어야겠고 , 기존 상태값이 객체 형태였으므로 , spread문법의 객체에서의 활용을 참고해서 만들것. 

또한 input이 여러개 이므로 name태그를 이용해서 특정 name키를 가진 input의 value를 컨트롤 해줄 수 있다는 점 - 그 input에 onChange가 발생하면, 해당하는 name태그를 가진 value값에 onChange가 발동 되는 구조.

문법은 [태그값] : 바꿔줄 값(여기서는 value)

 

useRef를 사용해서 객체를 만들면, 해당 상태에 업데이트가 일어날 때 리렌더링이 되지 않음. 

useState와 달리. 왜냐하면 useState는 상태를 바꿔주는 함수를 호출해서 렌더링을 일으키고 그 렌더링이 완료되면 업데이트 된 상태를 조회하는 방식임. 하지만 useRef는 상태를 설정하는 즉시 바로 조회가 가능하기 때문에 렌더링을 다시 할 필요가 없는것

 

 

2. 배열 렌더링하기

단순히 그냥 배열을 직접 하드코딩해서 그걸 그냥 화면에 보여줄 수 있음.

이때 User 컴포넌트를 만들어서 재사용이 가능하게 한다던지 map을 사용해서 배열을 뿌려준다던지 하는 부분을 활용해서 만들 수 있음

 

 

3. useRef() 로 id 관리하기 

"useRef()를 사용할 때 파라미터를 넣어주면 이 값이 .current 값을 수정하고 조회를 할 때는 .current를 조회하면 된다."

여기서는 말그대로 그냥 useRef로 컴포넌트 안에 변수를 (즉 상태를) 만들기만 한것임.

const nextId = useRef() 

nextId.current +=1

이렇게 해줬으니까 즉 1,2,3,4,5,6,7... 이런 상태값을 만든다는 의미임. 이걸 새로운 항목이 만들어질 때 id로 쓰겠다는 말이니까

새 항목이 추가 될 때마다 호출될수 있는 함수를 만들어서 그 안에 넣으면 됨.

 

 

 


 

 

 

https://react.vlpt.us/basic/14-array-remove.html

 

14. 배열에 항목 제거하기 · GitBook

14. 배열에 항목 제거하기 이 섹션에서 사용된 코드는 다음 페이지에서 확인 할 수 있습니다. 이번에는 배열에 항목을 제거 할 때에는 어떻게 해야 하는지 알아보겠습니다. 우선, UserList 에서 각 U

react.vlpt.us

 

 

등록된 명부 리스트에 삭제버튼을 추가해줘서

해당 버튼을 누르면 그 순서에 해당하는 유저정보가 사라지게끔 만들기

 

->

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(i =>(
                <User user={i} key={i.id} onRemove={onRemove}/>
            ))}
        </div>
    );
}



export default UserList;

 

 

App.js 해당 부분이 추가적으로 들어감

const onRemove= id =>{
    setUsers(users.filter(user => user.id !==id));
  };
  return(
    <>
    <CreateUser 
      username = {username}
      email = {email}
      onChange = {onChange}
      onCreate = {onCreate}
    />
    <UserList users={users} onRemove={onRemove}/>
    </>
  );

 

 

 

개념 1. 리액트에서의 함수 호출

onRemove 함수를 props로 전달해줘서 삭제 버튼을 누르면 해당 함수가 실행되도록 한다.

이때 onClick = {()=>{onRemove(user.id)}}

와 같이 익명 애로우 함수를 사용해주는 이유는 

 

만약 onClick={someFunction()} 을 해주게 되면

해당 컴포넌트가 렌더링 됨과 동시에 someFunction 함수는 실행 된다.

그래서 보통은 onClick = {someFunction} 과 같이 () 을 제외하는 형태로 함수를 호출하게 되는데,

 

여기서는 인자값으로 user.id를 받아와야 하므로

필연적으로 someFunction(user.id) 과 같은 형식을 사용하게 되는 것이다.

 

따라서 onClick = {someFunction(user.id)} 를 하게 되면

컴포넌트가 렌더링 되는 시점에서 해당 함수가 실행 되어버려서 결국 화면에는 아무것도 렌더링 되지 않을것이다.

 

따라서 onClick 에 콜백함수를 넣어줘서 해당 함수가 실행 될 때 user.id를 건내줘서 실행시키는 식으로 처리를 한 것이다.

 

 

개념 2. 함수의 인자 전달

onRemove 함수를 App.js 에서 만들어줬을 때 , 

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

이 부분에서 파라미터로 받은 id라는 값이 어디서 나온 것인지 잘 이해가 되지 않았다.

 

이 함수가 실행되는 button 즉 UserList 컴포넌트를 살펴보면 된다. 

여기서보면 button을 누르면 user.id 를 인자값으로 받도록 되어있다.

그러니까 결국 그 상위 컴포넌트에서 

users.map을 돌려서 해당하는 번째의 user 객체. 의 id값..!! 을 인자로 던져준것 !

 

돌아가서 App.js의 onRemove 함수를 보면 , 

파라미터도 이 값을 받아서 filter를 이용해 새로운 배열을 만들어낸 것이다.

그리고 users.filter(user=>user.id) 이 부분은 

인자명이 user라서 헷갈렸는데.. 

결국 그냥 인자라서

users 에 있는 값들을 필터 돌려서 각각 요소요소(여기서는 각 객체)의 id 값 <= 요걸 지칭하는 의미였다.

 

그래서 해당 요소요소의 아이디 값이랑 & 파라미터로 받아온 id 값 (여기서는 버튼을 누른 해당 객체의 id 값)

이 두개를 비교해서

같은 아이디 값을 가진 객체를 제외하고 새로운 배열을 만들어서

user 상태에 담아준 것이다~

 

 

 

 

 

 

 

 

 

 

반응형