[React] useRef

sue·2021년 1월 17일
0

react note

목록 보기
5/17

useRef로 특정 DOM 선택하기

html과 js를 사용할 때에는 특정 DOM을 선택해야하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택했다. 리액트를 사용하는 프로젝트에서도 DOM을 직접 선택해야 하는 일이 발생하는데, 그럴 때 ref를 사용하고, 함수형 컴포넌트에서는 useRef라는 Hook 함수를 사용한다.

초기화 버튼을 클릭했을 때 이름 input 에 포커스가 잡히도록 useRef 를 사용하여 기능 구현

import React, { useState, useRef } from "react";

export default function InputTest() {
  const [inputs, setInputs] = useState({ name: "", nickname: "" });

  const nameInput = useRef();
  // useRef()로 Ref 객체를 만듬 
  
  const { name, nickname } = inputs;


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

  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
    nameInput.current.focus();
    // 만든 Ref객체.current값은 DOM을 가리킴 
    // onReset함수 실행 시 ref로 설정한 input에 포커스 
  };

  return (
    <div>
      <input
        name="name"
        placeholder="이름"
        onChange={onChange}
        value={name}
        ref={nameInput}
	// 선택하고 싶은 DOM에 ref값으로 설정 
      />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>: </b>
        {name}({nickname})
      </div>
    </div>
  );
}

본질적으로 useRef는 .current 프로퍼티에 변경 가능한 값을 담고 있는 “상자”와 같다.

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

useRef Hook 은 DOM 을 선택하는 용도 뿐만 아니라, 다른 용도로도 사용된다. 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리하는 것이다.

기본적으로 리액트 컴포넌트는 내부 상태(state)가 변할 때마다 다시 랜더링이 된다. 대부분의 경우, 상태가 변할 때 마다 React 컴포넌트 함수가 호출되어 화면이 갱신되기를 바랄 것이다. 하지만 다시 랜더링이 되더라도 기존에 참조하고 있던 컴포넌트 함수 내의 값이 그대로 보존되야 하는 경우가 있다. (ex, 자동 카운팅)
이때 useRef를 사용하여 컴포넌트가 리렌더링 될 때 계속 기억할 수 있는 값을 관리할 수 있다.

주로 다음과 같은 상황에서 사용한다.

  • setTimeout, setInterval 을 통해서 만들어진 id값을 기억해야 할 때
  • 외부 라이브러리를 사용하여 생성된 인스턴스를 담을 때
  • scroll 위치를 알고 있어야할 때

배열에 새 항목을 추가할 때, 새 항목에서 사용할 고유 id를 관리할 용도로 useRef를 사용해본다. 먼저 App에서 배열을 선언하고, UserList에게 props로 전달해준다.

App.js

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

function App() {
  const users = [
    {
      id: 1,
      username: "su",
      email: "susu@gmail.com",
    },
    {
      id: 2,
      username: "liz",
      email: "lili@gmail.com",
    },
    {
      id: 3,
      username: "ro",
      email: "ro@gmail.com",
    },
  ];

  const nextId = useRef(4); 
  // 이 값이 바뀐다고 해서 컴포넌트가 리렌더링 될 필요가 없기 때문에 useRef 사용

  const onCreate = () => {
    console.log(nextId.current); //4
    nextId.current += 1; // 현재값에 +1 
  };

  return <UserList users={users} />;
}

export default App;

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

UserList.js

import React from "react";

function User({ user }) {
  // props로 user값을 받아옴
  return (
    <div>
      <b>{user.username}</b> <span>{user.email}</span>
    </div>
  );
}

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

0개의 댓글