본문 바로가기
Language/React

[React] 배열에 항목 추가하기

by 며루치꽃 2020. 12. 28.
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;

 

4개의 props를 받는데 username, email 과 이벤트 값이 바뀔 때 처리할 onChange함수, 버튼을 눌렀을  때 새로운 항목을 추가할 수 있는 onCreate 함수를 이용할 것입니다. 필요한 값들을 props 받아서 사용할 것입니다. 

 

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

제일 먼저 input의 상태를 관리하는 것이 필요합니다. 

여러개의 input을 관리하는데 useState를 사용하는데, 각각 useState를 사용하는 것이 아니라 useState에서 객체 형태로 상태를 만들어주면 됩니다. 여기서는 input이라는 상태를 만들어줍니다. 여기서 사용할 상태를 username과 email로 설정해줍니다.

const { username, email} = inputs; // 비구조화 할당을 통해 값을 꺼냅니다

비구조화 할당을 통해 값을 꺼내줍니다.

 

 const onChange = e => {
        const { name, value } = e.target;
        setInputs({
            ...inputs, // 기존의 input 값을 가져온다음에
            [name]: value // name이 username이면 username을 바꾸고 name이 email이다 하면 email을 바꿉니다
        })
    }

onChange는 이벤트를 가져와서 setInputs를 호출해주면 됩니다. setInputs는 기존의 내용을 더한 다음에,  받아온 name 값을 value로 덮어 씌워줍니다. name이 username이면 username을 바꾸고 name이 email이다 하면 email을 바꿉니다.

 

그리고 나서 createUser 컴포넌트에 넣어주면 됩니다. 

 

배열을 컴포넌트의 상태로서 관리하기 위해 useState로 감싸줍니다.

const [users, setUsers] = useState([
        {
            id: 1,
            username: 'kim',
            email: 'kim@naver.com'
        }, 
        {
            id: 2,
            username: 'test',
            email: 'test@naver.com'
        },
        {
            id: 3,
            username: 'aa',
            email: 'aa@naver.com'
        }
    ]);

 

배열에 변화를 줄 때에는 객체와 마찬가지로, spread 연산자를 통해 기존의 값을 복사하고 특정 값을 덮어 씌웠습니다.

배열도 마찬가지로 기존의 배열을 바꾸지 않으면서, 새로운 배열을 만들어줘야합니다. 

배열의 불변성을 지키면서 새로운 항목을 추가하는 방법은 

 

1. spread 연산자를 사용하는 것입니다.

const onCreate = () => {
        const user = { // 새로운 객체를 만들어주고 
            id: nextId.current,
            username,
            email,
        };

        setUsers([...users, user]); // 기존의 배열을 복사해서 넣은다음에 새로운 배열을 만들고 뒤에다가 user를 넣어주면 새로운 배열이 만들어집니다 



        setInputs({  // 버튼이 눌렸을 때 초기화되도록 
            username:'',
            email: ''
        });
        console.log(nextId.current); //4;
        nextId.current += 1;
    }

 

1) 새로운 객체를 만들어줍니다.

2) setUsers를 호출해주는데 기존의 배열을 복사해서 넣은다음에 새로운 배열을 만들고 뒤에다가 user를 넣어주면 새로운 배열이 만들어집니다 .

 

2. concat 함수를 사용하는 것 

여러개의 배열을 하나의 배열로 합쳐주는 것입니다.

setUsers(users.concat(user)); // 새로운 배열을 만들어서 괄호 안에 있는 user를 붙여줍니다. 

새로운 배열을 만들어서 괄호 안에 있는 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, // 기존의 input 값을 spread 연산자로 
            [name]: value // name이 username이면 username을 바꾸고 name이 email이다 하면 email을 바꿉니다
        })
    }

    const [users, setUsers] = useState([
        {
            id: 1,
            username: 'kim',
            email: 'kim@naver.com'
        }, 
        {
            id: 2,
            username: 'test',
            email: 'test@naver.com'
        },
        {
            id: 3,
            username: 'aa',
            email: 'aa@naver.com'
        }
    ]);

    const nextId = useRef(4);

    const onCreate = () => {
        const user = { // 새로운 객체를 만들어주고 
            id: nextId.current,
            username,
            email,
        };

        // setUsers(users.concat(user)); // 새로운 배열을 만들어서 괄호 안에 있는 user를 붙여줍니다. 

        setUsers([...users, user]); // 기존의 배열을 복사해서 넣은다음에 새로운 배열을 만들고 뒤에다가 user를 넣어주면 새로운 배열이 만들어집니다 
        setInputs({  // 버튼이 눌렸을 때 초기화되도록 
            username:'',
            email: ''
        });
        console.log(nextId.current); //4;
        nextId.current += 1;
    }

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

export default App

댓글