useRef는 처음이라 :: 개념부터 활용 예시까지

React2021-05-14 · 7 min read

들어가며

React 의 Hook 함수 중 하나인 useRef 에 대해 정리했습니다. useRef 의 개념과 대표적인 3가지 활용 방법을 예시 코드를 통해 살펴보겠습니다. 3가지 활용 방법은 다음과 같습니다.

  1. 특정 DOM 선택하기

  2. 컴포넌트 안의 변수 만들기

  3. 리렌더링 방지하기

1. useRef가 무엇인가요?

react-use-ref-1

사진 출처: livebook.manning.com

useRef 는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지됩니다. 본질적으로 useRef 는 .current 프로퍼티에 변경 가능한 값을 담고 있는 상자와 같습니다.

React 공식 문서에 적혀 있는 useRef 정의입니다. useRef 사용 예제를 통해 위 정의에 대해 자세히 알아보겠습니다.

2. useRef를 언제 사용하나요?

2-1. 특정 DOM 선택하기

react-use-ref-2

사진 출처: learnjavascriptfast.com

JavaScript 를 사용할 때는, 특정 DOM 을 선택해야 하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택합니다.

리액트에서는 DOM 을 선택할 때 ref 를 사용합니다. 함수형 컴포넌트에서 ref 를 사용할 때는 useRef Hook 함수를 사용하고 클래스형 컴포넌트에서는 콜백 함수를 사용하거나 React.createRef 함수를 사용합니다.

이 글에서는 함수형 컴포넌트의 useRef 를 사용합니다.

2-2. 컴포넌트 안의 변수 만들기

컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리할 수 있습니다.

useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않습니다. 리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고 다음 렌더링 이후 업데이트된 상태를 조회할 수 있지만, useRef 로 관리하는 변수는 설정 후 바로 조회할 수 있습니다.

이 변수를 사용하여 scroll 위치와 같은 값을 관리할 수 있습니다.

2-3. 리렌더링 방지하기

컴포넌트가 렌더링 된다는 것은 함수(컴포넌트)를 호출하여 실행되는 것을 말합니다. 함수가 실행될 때마다 내부에 선언되어 있던 표현식(변수나 또 다른 함수 등)도 매번 다시 선언되어 사용합니다. 컴포넌트는 자신의 state 가 변경되거나, 부모에게서 받는 props 가 변경되었을 때마다 리렌더링 됩니다.

useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않으므로 리렌더링 방지에 활용할 수 있습니다.

3. useRef로 DOM 선택하는 방법

useRef()를 사용하여 Ref 객체를 만들고, 이 객체를 선택하고 싶은 DOM 에 ref 값으로 설정합니다. 그러면, Ref 객체의 .current 값은 DOM을 가리키게 됩니다.

이 포스팅에서 다룰 예제에서는 onReset 함수에서 input 에 포커스를 하는 focus() DOM API 를 호출했습니다. 초기화 버튼을 클릭했을 때 이름 input 에 포커스가 잡히도록 useRef 를 사용하여 기능을 구현했습니다.

3-1. 객체 생성하기

useRef 를 통해 nameInput 이라는 객체를 생성했습니다.

const nameInput = useRef();

3-2. DOM API 사용

current 가 DOM 을 가리키고 있으므로 DOM API 중 하나인 focus 를 사용했습니다.

nameInput.current.focus();

3-3. DOM 설정을 통해 DOM에 직접 접근하기

nameInput 객체를 선택하고 싶은 DOM 에 설정하여 직접 접근할 수 있습니다.

<input name="name" placeholder="이름" onChange={onChange} value={name} ref={nameInput} />

3-4. 예제 전체 코드

InputSample.js

import React, { useState, useRef } from 'react'; function InputSample() { const [inputs, setInputs] = useState({ name: '', nickname: '', }); const nameInput = useRef(); const { name, nickname } = inputs; const onChange = e => { const { value, name } = e.target; setInputs({ ...inputs, [name]: value, }); }; const onReset = () => { setInputs({ name: '', nickname: '', }); nameInput.current.focus(); }; return ( <div> <input name="name" placeholder="이름" onChange={onChange} value={name} ref={nameInput} /> <input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname} /> <button onClick={onReset}>초기화</button> <div> <b>값: </b> {name} ({nickname}) </div> </div> ); } export default InputSample;

App.js

import React from 'react'; import InputSample from './InputSample'; function App() { return <InputSample />; } export default App;

3-5. 실행 결과

초기화 버튼을 클릭했을 때 이름 input 에 포커스가 잡힙니다.

react-use-ref-3

4. useRef로 컴포넌트 안의 변수 만드는 방법

useRef()를 사용할 때 파라미터를 넣어주면, 이 값이 .current 값의 기본값이 됩니다. 그리고 이 값을 수정할 때는 .current 값을 수정하면 되고 조회할 때도 .current 를 조회하면 됩니다.

4-1. useRef의 파라미터

현재 3개의 id 가 있으므로 다음 id 의 기본값을 4로 지정했습니다.

const nextId = useRef(4);

4-2. 예제 전체 코드

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;

App.js

import React, { useRef, useState } from 'react'; import UserList from './UserList'; 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: 'minzidev', email: 'minzidev@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, }; console.log(user.id); setUsers(users.concat(user)); setInputs({ username: '', email: '', }); nextId.current += 1; }; return ( <> <div> <input name="username" placeholder="계정명" onChange={onChange} value={username} /> <input name="email" placeholder="이메일" onChange={onChange} value={email} /> <button onClick={onCreate}>등록</button> </div> <UserList users={users} /> </> ); } export default App;

4-3. 실행 결과

id 값으로 nextId.current 를 사용합니다.

react-use-ref-4

5. 리렌더링 방지하는 방법

위 예시 코드에는 input 값이 변경될 때마다 리렌더링 된다는 단점이 있습니다.

onChange 구현 부분을 ref 값으로 대체해서 단점을 해결할 수 있습니다. stateeventvalue 에 접근하지 않고 refObject.current.value 를 사용하는 방법입니다.

5-1. ref 속성 사용하기

inputonChangeref 속성으로 대체했습니다.

<div> <input name="username" placeholder="계정명" ref={usernameRef} /> <input name="email" placeholder="이메일" ref={emailRef} /> <button onClick={onCreate}>등록</button> </div>

5-2. 예제 전체 코드

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;

App.js

import React, { useRef, useState } from 'react'; import UserList from './UserList'; import InputSample from './InputSample'; function App() { const [inputs, setInputs] = useState({ username: '', email: '', }); const [users, setUsers] = useState([ { id: 1, username: 'minzidev', email: 'minzidev@gmail.com', }, { id: 2, username: 'tester', email: 'tester@example.com', }, { id: 3, username: 'liz', email: 'liz@example.com', }, ]); const nextId = useRef(4); const usernameRef = useRef(''); const emailRef = useRef(''); const onCreate = () => { const user = { id: nextId.current, username: usernameRef.current.value, email: emailRef.current.value, }; setUsers(users.concat(user)); setInputs({ username: '', email: '', }); nextId.current += 1; }; console.log('Render'); return ( <> <div> <input name="username" placeholder="계정명" ref={usernameRef} /> <input name="email" placeholder="이메일" ref={emailRef} /> <button onClick={onCreate}>등록</button> </div> <UserList users={users} /> <InputSample /> </> ); } export default App;

5-3. 실행 결과

처음 컴포넌트를 불러왔을 때, 등록 버튼을 눌렀을 때 2번만 렌더링 되는 것을 확인할 수 있습니다.

react-use-ref-5

마치며

useRef 개념에 대해 알아본 후 대표적인 3가지 활용 방법을 예제와 함께 정리했습니다.

  1. 특정 DOM 선택하기

  2. 변수 생성하기

  3. 리렌더링 방지하기

참고 자료

타 사이트에서 블로그를 운영할 때 작성한 글을 이전했습니다. 🙂

profile

김민지

안녕하세요 👋 개발자 김민지입니다. 방문해 주셔서 감사합니다.

최신글 보러가기

thumbnail

예측할 수 있는 UX로 서비스 신뢰도 높이기

간단한 수정 사항으로 비효율적인 페이지 이동을 개선하고 이를 히트맵과 레코딩 기반으로 분석한 결과를 소개해요.

2025-08-02 · 4 min read

thumbnail

Floating UI를 활용한 툴팁 컴포넌트 생성 과정

툴팁 컴포넌트의 포지션 설정 방식을 변경하여 모바일 대응성을 높이고 개발자 경험도 개선한 사례에 대해 정리했어요.

2025-05-03 · 6 min read

thumbnail

프론트엔드 개발 일 년 차 회고

프론트엔드 개발자로서 첫 일 년 동안의 경험을 시간순으로 정리했어요. 간단한 텍스트 수정 업무부터 새로운 기능을 도입하는 큰 프로젝트 업무까지 참여하며 배운 점과 아쉬운 점을 담았어요.

2024-12-23 · 9 min read

logo
© 2021-2025 김민지 All Rights Reserved.

Links

HomeCategoryArchive

Contact