useRef
의 필요성에 대해 학습한다.useRef
가 필요한 상황들을 기억한다.useRef
의 사용법을 이해한다.React는 아래와 같이 DOM 엘리먼트의 주소값을 활용해야 하는 경우 사용하는 Hook이 있습니다.
React는 이런 예외적인 상황에서 useRef
로 DOM 노드, 엘리먼트, 그리고 React 컴포넌트 주소값을 참조할 수 있습니다.
아래 예시 코드처럼 작성하면 주소값을 활용할 수 있습니다.
const 주소값을_담는_그릇 = useRef(참조자료형)
// 이제 주소값을_담는_그릇 변수에 어떤 주소값이든 담을 수 있습니다.
return(
<div>
<input ref={주소값을_담는_그릇} type="text"/>
{/* React에서 사용 가능한 ref라는 속성에 주소값을_담는_그릇을 값으로 할당하면*/}
{/* 주소값을_담는_그릇 변수에는 input DOM 엘리먼트의 주소가 담깁니다. */}
{/* 향후 다른 컴포넌트에서 input DOM 엘리먼트를 활용할 수 있습니다. */}
</div>);
)
이 주소값은 컴포넌트가 재렌더링 되더라도 바뀌지 않습니다.
React 컴포넌트는 기본적으로 내부 상태(state)가 변할 때마다 다시 렌더링(rendering)됩니다.
import React, { useState, useRef } from "react";
export default function App() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
const increaseCountState = () => {
setCount(count + 1);
console.log("state:", count);
};
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log("Ref :", countRef.current); //countRef.current
};
return (
<div>
<p>State: {count}</p>
<p>Ref: {countRef.current}</p>
<button onClick={increaseCountState}>State 올려</button>
<button onClick={increaseCountRef}>Ref 올려</button>
</div>
);
}
아래 예제에서는 state
가 증가할 때마다 App 컴포넌트가 재렌더링 되기 때문에 콘솔창에서 'state 올려' 버튼을 클릭한 횟수만큼 다시 렌더링이 되는 걸 확인할 수 있습니다.
반면에 'Ref 올려' 버튼을 클릿한 횟수는 콘솔창에 보이지만 브라우저 상에서는 확인할 수 없다는 걸 확인할 수 있습니다.
useRef
는 아무리 수정을 해도 해당 컴포넌트를 다시 렌더링시키지 않기 때문입니다.
App 컴포넌트 내부적으로는 countRef
객체가 증가하고 있는 것은 맞지만 렌더링이 되지 않고 있기 때문에 아무리 증가해도 브라우저에 보이지 않습니다.
이 상태에서 다시 'state 올려' 버튼을 누른다면 App 컴포넌트가 렌더링되면서 countRef
의 값도 업데이트가 된 걸 확인할 수 있습니다.
위 내용을 정리하면 아래와 같습니다.
렌더링이 되지 않는다는 특징으로 인해 useRef
통해 성능 향상을 시킬 수 있습니다.
또한 useRef
를 이용해 DOM 요소에 접근할 수 있습니다.
대표적으로는 input
요소를 클릭하지 않아도 focus()를 주고 싶을 때 많이 사용합니다.
useRef
함수는 current
속성을 가지고 있는 객체를 반환하는데, 인자로 넘어온 초기값을 current
속성에 할당합니다. 이 current
속성은 값을 변경해도 상태를 변경할 때처럼 React 컴포넌트가 다시 렌더링되지 않습니다.
React 컴포넌트가 다시 렌더링될 때에도 current
속성의 값은 사라지지 않습니다.
// 기본 형태
const ref = useRef(value)
// ref 객체
{current: value}
// 예시
const ref = useRef("hi")
// ref 객체
{current: "hi"}
// ref 객체
ref.current = "hello"
{current: "hello"}
아래의 코드처럼 렌더링이 될때마다 실행되는 useEffect 함수에서도 useRef를 사용함으로써 재렌더링되지 않게 할 수 있습니다.
만약 useEffect안에 useState를 사용했다면 계속 렌더링되는 상황이 발생할 수도 있습니다.
useRef
를 이용해 DOM 요소에 접근하는 방법은 useRef를 접근하고자하는 DOM 요소에 넣어주기만 하면 됩니다. 아래 코드를 통해 input요소에 접근했다면 value값도 사용할 수 있습니다.
const ref = useRef(value)
// useRef를 접근하고자하는 DOM 요소에 넣어주기만 하면 됩니다.
<input ref={ref}/>