본문 바로가기
fastcampus

[패스트캠퍼스 수강 후기] 프론트엔드 인강 100% 환급 챌린지 20회차 미션

by 새우하이 2020. 9. 26.

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

useRef를 사용해서 컴포넌트 안의 변수를 만들것이다.
여기서 말하는 변수는 예를들어 컴포넌트 내부에서 let키워드를 사용하여 변수를 선언한다고 가정할 때 다음 리렌더링 때는 이 변수값이 초기화된다. 유지를 위해서는 useState를 사용해야하는데 이것은 상태가 바뀌게되면 컴포넌트가 리렌더링된다. 하지만 우리는 값을 바꿨을때 굳이 리렌더링할 필요없는 경우가 있다. 그럴때 useRef를 사용해서 컴포넌트가 리렌더링 될 때마다 계속 기억해야할 값을 관리할 때도 사용할 수 있다. 주로 setTimeout이나 setInterval을 사용할 때 주어지는 id값을 기억해야할 때나 외부라이브러리를 사용해서 생성된 인스턴스를 담을때도 사용하고, scroll위치를 알아야할 때 등등 다양한 경우에 사용할 수 있다.
중요한 것은 useRef로 관리하는 값은 바뀌어도 컴포넌트가 리렌더링 되지 않는다.

우리는 App컴포넌트에서 useRef를 사용해서 변수를 관리해 볼 것인데, 용도는 우리가 앞으로 배열에 새 항목을 추가할 때 그 항목의 고유아이디값을 관리하기 위함이다.

/*UserList.js*/

 const users =[
        {
            id: 1,
            username: 'jiwon',
            email: 'pannchat@likelion.org'
        },
        {
            id: 2,
            username: 'tom',
            email: 'tom@tom.org'
        },
        {
            id: 3,
            username: 'sam',
            email: 'sam@sam.org'
        },
    ];

이렇게 선언되어있는 users를 UserList 컴포넌트의 props로 받아오게 해준다.

function UserList({users}){

그리고 users라는 배열을 App.js로 옮겨준다.

/* App.js */
import React from 'react';
import UserList from './UserList';
function App() {
  const users =[
    {
        id: 1,
        username: 'jiwon',
        email: 'pannchat@likelion.org'
    },
    {
        id: 2,
        username: 'tom',
        email: 'tom@tom.org'
    },
    {
        id: 3,
        username: 'sam',
        email: 'sam@sam.org'
    },
];
  return (
    <UserList users={users}/>
  )
}

export default App;

그리고 를통해 UserList로 전달해준다.
이제 userRef를 사용해서 nextId라는 변수를 만들어 보자.
js import React,{ useRef } from 'react';

useRef를 불러와주고
nextId라는 값을 관리하기 위한 변수를 선언해주고 초기값을 4로 지정해줄 것.
현재 users에 id: 3까지 정의했기 때문에 4로 설정함.

const nextId = useRef(4);

그리고 앞으로 새로운 항목을 추가할 때 사용할 함수를 미리 구현해보자

const onCreate = () => {
  console.log(nextId.current);
}

이렇게 정의한뒤 호출하면 console.log(nextId.current); 를통해 nextId.current값을 조회하면 4가 출력될 것이다.
또, 새로운 항목을 만들 때마다 nextId의 current값을 변화시킬텐데.
이것은 nextId.current += 1; 을 추가해줘서 값을 변경 해 줄수있다.
여기서 nextId를 useRef로 관리해주는것은 이 값이 바뀐다고해서 굳이 컴포넌트가 리렌더링 될 필요가 없기 때문이다.

요약하자면 useRef는 특정 DOM을 선택하고 싶을때 사용할 수도 있지만 어떤 변수를 계속 기억하고 싶을때, 컴포넌트가 리렌더링되어도 기억하고 싶을때 사용할 수 있다. 따라서 이 값이 바뀐다고해서 컴포넌트가 리렌더링 되지 않는다는 것을 알아둬야한다

배열에 항목 추가하기

배열에 새로운 항목을 추가하는 방법을 알아보기위해
CreateUser라는 컴포넌트를 생성한다.
우선 function CreateUser를 생성해주고 props 4개를 받아올 것이다.
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;

jsx코드를 바로 반환해주는 CreateUser를 생성해주고
input 2개와 button을 생성한다.
그리고 여기에 필요한 값들을 설정해준다.
button 의 onClick에 onCreate함수를 넣어주면 버튼이 클릭될때 onCreate함수가 호출된다.
이 함수는 props에서 받아오는 것.

이제 App컴포넌트를 수정한다.

/* App.js */
.
.
  return (
    <>
    <CreateUser />
    <UserList users={users}/>
    </>
  )

2개의 컴포넌트를 렌더링하기 위해 <> 프레그먼트로 감싸고 CreateUser를 렌더링해준다.

이제 CreateUser에서 필요한 Props들을 App 에서준비한다. 여러개의 input값을 관리하기 위해 useState를 사용하는데 useState를 두 번 사용하지 않고 객체형태로 만들어준다.

  const [inputs, setInputs] = useState({
    username: '',
    email: '',
  });
  const {username, email} = inputs;
  const onChange = e =>{
    const {name, value} = e.target;
    setInputs({
      ...inputs,
      [name] : value
    });
  };

inputs와 setInputs라는 상태를 만들어주고 username과 email을 공백으로 설정.
그리고 inputs에서 username, email을 추출.
onChange를 구현하는데 event e를 가져와서 const {name,value} = e.target 으로 name,value를 e.target에서 가져오도록 설정하고.
setInputs를 호출하면서 ...inputs로 기존의 내용을 호출하고 받아온 name값을 value로 덮어씌운다.
그리고 CreateUser에 방금 만든것들을 넣어준다.

/* App.js */
    <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/>

이제 onCreate에서 버튼이 클릭 될 때 input의 값이 지워지도록 해보자.

/* App.js */
const onCreate = () => {
  setInputs({
    username:'',
    email:'',
  });
  console.log(nextId.current);
  nextId.current += 1;
}

그리고 users 배열을 컴포넌트의 상태로써 관리해주게 만드는데 방법은. useState로 감싸주고 users,setUsers를 추출해주면된다.

이번에는 배열에 변화를 줄 차례이다.
users.push나 splice나 sort같은 함수를 사용할 수 없다.
기존의 배열을 바꾸지않고 새로운 배열을 생성하고 거기에 변화를 주는 방식으로 사용해야 하기때문이다. 굳이 사용해야한다면 배열을 복사하고나서 해야함.

첫번째 방법으로 spread연산자를 사용한다.
일단 onCreate에서 새로운 user객체를 만들어준다

/* App.js */
  const user ={
    id : nextId.current,
    username,
    email,
  };

id값은 nexId.current 값을 사용하고. username과 email은 현재 input 이 가리키는 값을 사용한다.

/* App.js */
  setUsers([...users,user]);

그리고 setUsers에 ...users spread연산자로 기존의 배열을 불러와주고 새로 추가된 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: 'jiwon',
        email: 'pannchat@likelion.org'
    },
    {
        id: 2,
        username: 'tom',
        email: 'tom@tom.org'
    },
    {
        id: 3,
        username: 'sam',
        email: 'sam@sam.org'
    },
]);

const nextId = useRef(4);
const onCreate = () => {
  const user ={
    id : nextId.current,
    username,
    email,
  };
  setUsers([...users,user]);
  setInputs({
    username:'',
    email:'',
  });
  console.log(nextId.current);
  nextId.current += 1;
}
  return (
    <>
    <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/>
    <UserList users={users}/>
    </>
  )
}

export default App;

여기까지 실행시켜보면 잘 추가되는것을 확인가능함.

두번째 방법은 concat함수를 사용하는것인데.
concat는 여러개의 배열을 하나로 합쳐주는데 굳이 배열 + 배열 이아니더라도
배열 + 요소 로 실행해도 잘 생성된다.

  setUsers(users.concat(user));

이부분만 이렇게 바꿔줄 수 있다.

해당 내용은 아래 링크에서 수강할 수 있다.

프론트엔드 개발 올인원 패키지 with React Online. 👉https://bit.ly/2ETLEzm

 

프론트엔드 개발 올인원 패키지 with React Online. | 패스트캠퍼스

성인 교육 서비스 기업, 패스트캠퍼스는 개인과 조직의 실질적인 '업(業)'의 성장을 돕고자 모든 종류의 교육 콘텐츠 서비스를 제공하는 대한민국 No. 1 교육 서비스 회사입니다.

www.fastcampus.co.kr

 

댓글