[리액트] useRef
◼ useRef
useRef는 React에서 사용되는 특별한 훅(Hook) 중 하나입니다. 이 훅을 사용하면 함수형 컴포넌트 내에서 "참조(reference)"를 생성할 수 있습니다.
참조는 일종의 특별한 객체로, DOM 요소나 다른 React 요소에 접근하는 데 사용됩니다. useRef를 사용하여 생성된 참조는 컴포넌트의 렌더링과는 관련이 없으며, 컴포넌트의 생명주기와 관련된 일반적인 훅과는 달리, 컴포넌트의 전체 렌더링 과정과는 독립적으로 존재합니다.
useRef를 사용하여 생성된 참조는 .current 속성을 통해 현재 값에 접근할 수 있습니다. 이 .current 속성은 초기에는 전달된 인자로 설정되며, 나중에 변경할 수도 있습니다.
일반적으로 useRef는 다음과 같은 목적으로 사용됩니다:
- DOM 참조 관리: React 컴포넌트 내에서 DOM 요소에 직접적인 접근이 필요한 경우 useRef를 사용합니다. 예를 들어, 특정 DOM 요소의 크기나 위치를 측정하거나, 해당 요소에 포커스를 설정하거나 해제하는 등의 작업을 수행할 때 사용됩니다.
- 이전 값의 보존: useRef를 사용하여 컴포넌트의 렌더링 간에 값이 보존되도록 할 수 있습니다. 이전 렌더링에서의 값을 저장하고 다음 렌더링에서 사용할 수 있습니다. 이를 통해 컴포넌트가 리렌더링될 때마다 값을 재설정하지 않아도 되는 경우에 유용합니다.
- 컴포넌트 간의 통신: useRef를 사용하여 다른 컴포넌트에 대한 참조를 저장하고 전달할 수 있습니다. 이를 통해 부모 컴포넌트가 자식 컴포넌트에게 명령을 내리거나, 자식 컴포넌트가 부모 컴포넌트에게 정보를 전달할 수 있습니다.
- 사용자 지정 인스턴스 변수: 클래스 컴포넌트의 인스턴스 변수와 비슷하게 useRef를 사용하여 함수형 컴포넌트 내에서 인스턴스 변수를 만들 수 있습니다. 이를 통해 컴포넌트의 렌더링 간에 상태를 보존하거나, 특정 작업을 수행할 수 있습니다.
◼ 랜더링이 일어나지 않아
컴포넌트의 전체 렌더링 과정과는 독립적으로 존재라, useRef를 사용하면 랜더링이 일어나지 않습니다.
이벤트 함수와 console.log는 그저 JavaScript 코드가 실행된 결과입니다. React 컴포넌트 내에서 사용되더라도 이벤트 함수나 console.log는 React의 가상 DOM 렌더링 과정과는 별개로 동작합니다.
예시 코드를 만들어 보았습니다.
버튼을 클릭하면, useRef로 연결된 refNum이 증가하게 하였습니다. 그리고 그 값을 자식에게 props로 전달한 상황입니다.
export default function Test({num}) {
console.log('자식');
return <div> 자식:{num}</div>
}
import Test from "./Test";
function Register() {
const refNum = useRef(0)
const plus = (e) => {
refNum.current++
console.log(refNum.current);
}
console.log('부모');
return (
<div>
부모:{refNum.current}
<Test num={refNum.current.value}/>
<button onClick={plus} >제출</button>
</div>
)
}
export default Register
plus 함수 안에 있는 console.log(refNum.current)의 값은 계속 증가합니다.
부모:{refNum.current}, 자식:{num} 은 증가되는 값이 표현되지 않습니다.
console.log('부모'), console.log('자식')도 첫 랜더링 이후 출력되지 않습니다.
◼ useRef로 랜더링을 일으킬수 있어
useRef가 랜더링과는 독립적으로 사용되지만, 전혀 랜더링을 일으키지 못하는것은 아닙니다.
ref를 JSX의 일부로 사용하여 참조된 DOM 요소를 렌더링하면 가능 합니다.
간단한 예시로 코드를 작성해 보았습니다.
import React, { useRef, useEffect, useState } from 'react';
function MyComponent() {
const ref = useRef(null);
const [count, setCount] = useState(0);
useEffect(() => {
// ref가 설정되면 해당 DOM 요소의 내용을 변경합니다.
if (ref.current) {
ref.current.innerHTML = `Count: ${count}`;
}
}, [count]);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<button onClick={handleClick}>증가</button>
<div ref={ref}></div>
</div>
);
}
export default MyComponent;
useState에 변수 값을 이용하여 값을 변경합니다.
위의 코드에서는 useRef로 ref를 생성하고, 해당 ref를 div 요소의 ref 속성으로 설정했습니다. 그리고 useEffect 훅을 사용하여 count 상태가 변경될 때마다 ref.current가 업데이트되고, 해당 DOM 요소의 내용이 변경되도록 설정하였습니다.
이렇게 하면 useRef로 생성된 참조를 사용하여 렌더링을 일으킬 수 있지만, 일반적으로 이 방법은 특별한 상황에만 사용되며, 컴포넌트의 상태나 props를 사용하여 렌더링하는 것이 더 바람직합니다.