🤩 useRef 🤩
useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지될 것입니다.
useRef는 리액트 훅의 한 종류로, Ref는 reference(참조)의 줄임말이다.
useRef를 이용하면 특정한 DOM요소에 접근이 가능하면, 불필요한 재렌더링을 하지 않는다는 장점이 있다.
1. 형식
1️⃣ 생성
const 변수명 = useRef(초기값)
useRef는 변수명에 초기값을 적는 식으로 만든다.
➡️ 이러한 결과값으로, {current: 초기값} 을 지닌 객체가 반환된다.
useRef에서 기억할 것은 이러한 current라는 키값을 지닌 프로퍼티가 생성되고, 값에 어떤 변경을 줄때도 이 current를 이용해서 한다는 점이다.
2️⃣ 반환요소에 접근
<input ref= {변수명}/>
2. 특징
반환된 useRef 객체는 컴포넌트의 전생애주기를 통해 유지가 된다.
1️⃣(= 컴포넌트가 계속해서 렌더링이 되어도 컴포넌트가 언마운드되기 전까지는 값을 그대로 유지할 수 있다)
2️⃣(= currnet 속성은 값을 변경해도 상태를 변경할 때 처럼 React 컴포넌트가 재렌더링 되지 않는다. )
🔫 렌더링과 상관없이, 마운트된 시점부터 언마운트된 시점까지 값을 유지한다 🔫
3. 언제 사용?
1️⃣ 저장공간
ref는 state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.
State의 변화 ➡️ 렌더링 ➡️ 컴포넌트 내부 변수들 초기화 |
Ref의 변화 ➡️ No 렌더링 ➡️ 변수들의 값이 유지됨 |
State의 변화 ➡️ 렌더링 ➡️ 그래도 Ref의 값은 유지됨 |
✅ 변경시 렌더링을 발생시키지 말아야하는 값을 다룰때 사용한다
(변화는 감지해야하지만, 그 변화가 렌더링을 발생시키면 안될때!!)
2️⃣ DOM요소에 접근
✅ useRef를 사용하면 손쉽게 input에 접근할 수 있다.
바닐라 자바스크립트의 getElementById, querySelector와 비슷하다.
<DOM요소 접근의 대표적인 예>
대표적으로 Input요소를 클릭하지 않아도 focus를 줄때 사용
4. 장점
자주 변경되는 값을 state에 담으면, 변경될때마다 재렌더링이 일어나서 성능에 안좋은 영향을 미친다.
하지만 useRef를 이용하면 값이 변경될때마다 렌더링이 일어나지 않는다 ➡️ ⭐️ 성능향상!! ⭐️
5. 일반 변수와의 차이점
state는 변경될때마다 재렌더링이 일어나고, ref는 변경이 되어도 렌더링이 일어나지 않는다는 점을 알았다.
그러면 일반
변수에서 선언한 값과는 어떤 차이가 있을까?
const countVar = 0; 이라는 변수를 선언하고 버튼을 누르면 그값에 +1을 하는 함수를 만들었다고 해보자.
const App = () => {
const countVar = 0;
const increaseVar = () => {
countVar = countVar +1;
}
return (
<div>
<p>Var: {countVar} </p>
<button onClick={increaseVar}> Var올려 </button>
</div>
)
Var올려 버튼을 누르고 렌더링을 해주면 var는 몇이 나올까?
정답은 0이다.
렌더링을 해준다는 것은 함수를 처음부터 다시 실행한다는 것을 의미한다.
그래서 렌더링을 할때마다 App컴포넌트를 나타내는 함수가 다시 불린다. 그러면 함수가 불릴때마다 이 함수 내부에 있는 변수들이 다시 초기화가 된다.
따라서 렌더링이 될때마다 const countVar = 0; 를 통해서 countVar라는 변수에는 계속해서 0으로 초기화가 된다.
🤔 useRef훅을 이용한 값과의 비교
ref의 값은 컴포넌트의 전생애주기를 통해서 관리되기 때문에, 아무리 컴포넌트가 렌더링 되더라도 언마운트가 되기 전까지는 값을 계속해서 유지한다.
✅ ref는 렌더링이후에도 값이 유지되지만, 변수는 초기화된다.
5. 대표적인 예시
input요소에 focus를 주고 싶을때 많이 사용한다.
ex>로그인 화면에서 id를 입력하는 칸을 클릭하지 않아도 자동적으로 focus가 되어있게 해주면, 키보드만 사용해도 바로 id를 입력할 수 있어서 편리하다.
리셋버튼을 누르면 맨앞에 있는 input에 focus가 들어가는 코드를 짜도록 해보자.
앞서서 input여러개 관리하기 연습한 코드에 이어서 만들어보았다.
import React, { useState, useRef } from "react";
const InputSample = () => {
const [inputs, setInputs] = useState({
이름: "",
nickname: "",
});
const nameFocus = useRef();
const { 이름, nickname } = inputs;
const onChange = (e) => {
const { value, name } = e.target;
setInputs({
...inputs,
[name]: value,
});
};
const onReset = () => {
setInputs({
이름: "",
nickname: "",
});
nameFocus.current.focus();
};
return (
<div>
<input
name="이름"
placeholder="이름쓰세요"
onChange={onChange}
value={이름}
ref={nameFocus}
/>
<input
name="nickname"
placeholder="닉네임쓰세요"
onChange={onChange}
value={nickname}
/>
<button onClick={onReset}>초기화</button>
<div>
<b>값:</b>
{이름}({nickname})
</div>
</div>
);
};
export default InputSample;
1️⃣ const nameFocus = useRef();
nameFocus라는 변수명을 지어서 useRef()의 초기값을 빈값으로 할당하였다.
2️⃣ onReset 함수안에 nameFocus.current.focus()
const onReset = () => {
setInputs({
이름: "",
nickname: "",
});
nameFocus.current.focus();
};
onReset를 누르면
useRef를 통해 만든 객체인 nameFocus안에 current에 focus()를 준다.
3️⃣ input안에 ref 속성값으로 {변수명}을 적는다.
<input
name="이름"
placeholder="이름쓰세요"
onChange={onChange}
value={이름}
ref={nameFocus}
/>
실제로 focus가 일어날 input에 ref라는 속성을 통해 변수명을 전달한다.
초기화버튼을 눌렀을때, 위와같이 focus버튼이 첫번째 input에 생긴것을 확인해볼수있다.
useRef란 무엇인지, 그 특징과 사용이유를 중점으로 공부해보았다.
렌더링을 계속해서 발생시키지 않기때문에 성능에 도움이 될 수 있고, ref를 이용해서 쉽게 DOM요소에 접근할 수 있다는 것이 흥미로웠다.
앞으로 프로젝트를 하면서 또 사용해보고 추후에 알게 된 점이 있다면 블로그에 기록해둬야겠다.
🤓 useRef 요약 🤓
//생성
const 변수명 = useRef(초기값)
// {current: 초기값} 을 지닌 객체가 반환됨
//반환요소에 접근
<input ref={변수명}/>
1️⃣ 변화는 감지하지만 렌더링 발생 X ➡️ 성능향상 (state는 변화시, 재렌더링됨)
2️⃣ DOM요소에 손쉽게 접근 (ref속성 사용)
3️⃣ 전생애주기를 통해 유지 (언마운트 되기전까지는 값을 계속 기억함)
참고자료
React Hooks에 취한다 - useRef 완벽 정리 1# 변수 관리 | 리액트 훅스 시리즈 (별코딩)
React Hooks에 취한다 - useRef 완벽 정리 2# DOM 요소 접근 | 리액트 훅스 시리즈(별코딩)
useRef로 특정 DOM 선택하기 (벨로퍼트와 함께하는 모던 리액트)
'React' 카테고리의 다른 글
contextAPI와 useContext 사용법 (다크모드 구현하기) (1) | 2023.03.15 |
---|---|
리액트 추가하기(Create)기능구현 /input 리셋 / 앞뒤빈칸제거 (1) | 2023.03.14 |
리액트로 간단한 CRUD완성 (3) | 2023.03.13 |
리액트 uuid 설치 (리액트 고유id, 고유key 사용이유) (0) | 2023.03.01 |
리액트 여러개의 input상태관리 (State관리) (5) | 2023.02.28 |