Frontend/React

useRef로 컴포넌트 안의 변수 만들기 & 배열에 항목 추가하기

silver님 2024. 8. 9. 17:07

useRef로 컴포넌트 안의 변수 만들기 & 배열에 항목 추가하기 

 

계정명과 이메일을 입력해주고 등록을 눌러주면 배열 목록에 등록과 동시에 입력값들이 초기화 된 것을 볼 수 잇음.

 

 

컴포넌트에서 특정 DOM을 선택해야할 때 -> ref 사용

함수형 컴포넌트에서 이를 설정할 때 -> useRef 사용 

 

useRef Hook은 DOM을 선택하는 용도 외에도, 컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리함.

 

App 컴포넌트에서 userRef를 사용해 변수를 관리하려 한다. 

사용하려는 목적은 배열에 새 항목을 추가하려 할 때, 새 항목에서 사용 할 고유 id를 관리하는 용도이다. 

 

useRef를 사용하여 변수를 관리하기 전에 배열을 App에서 선언하고 UserList에게 props로 전달해주는 방식으로 만들 것이다. 

 

 

1. useRef로 컴포넌트 안의 변수 만들기

App.js

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

function App() {
  const users = [
    {
      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 = () => {
    // 나중에 구현 할 배열에 항목 추가하는 로직
    // ...

    nextId.current += 1;
  };
  return <UserList users={users} />;
}

export default App;

 

userRef() 를 사용할 때 파라미터를 넣어주면 이 값이 .current값의 기본값이 된다.

그리고 이 값을 수정할 때 .current 값을 수정하면 되고 조회할 때는 .current를 조회하면 된다. 

 

UserList.js

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

export default UserList;

 


2. 배열에 항목 추가하기 

배열에 새로운 항목을 추가하려 한다.

 

일단 input두개와 button 하나로 이루어진 CreateUser.js 컴포넌트를 src 안에 만들어준다. 

 

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;

 

 

상태관리를 CreateUser에서 하지 않고 부모 컴포넌트인 App에서 하게 하고, input의 값 및 이벤트로 등록할 함수들을 props로 넘겨받아서 사용해주려한다.

 

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;

 

- input에 값을 입력하고 등록 버튼을 눌렀을 때 input 값들이 잘 초기화 되도록 만들어줬다. 

- users도 useState를 사용해 컴포넌트 상태로서 관리해줬다. 

- 불변성을 지키면서 배열에 새 항목을 추가해주기 위해 spread 연산자를 사용해줬다. 

+ 추가로 concat함수를 사용해서 기존의 배열을 수정하지 않고, 새로운 원소가 추가된 새로운 배열을 만들어주는 방법도 있다. 

 

 

App.js에서 concat함수를 사용한 부분 

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

 

 

🔑 핵심 포인트 

spread 연산자 사용 

- setUsers([...users, user]);

 

Concat 함수 사용 

- setUsers(users.concat(user));

 

✨ 부모 컴포넌트에서 state 값(input 등등)과 함수를 작성하고 자식 컴포넌트에게 전달하는 구조를 기억하자

 

728x90
반응형