Dom노드나 React엘리먼트에 접근하는 것이 가능하다.
값이 변경되어도 re-render를 일으키지 않는다.
useRef()는 일반적인 JS 객체이다.
즉, heap영역에 저장되는 변수이다.
실제로 useRef를 코드로 확인해보면 순수 자바스크립트 객체로 만들어진 hooks이다.
간단하게 말해서, 렌더링이 필요하면 useState
를 쓰면 되고 아닐 경우 useRef
를 써야한다.
import { useRef, useState } from "react"; export default function Ref() { const ref = useRef(0); const [state, setState] = useState(0); function handleClick() { ref.current = ref.current + 1; alert("You clicked " + ref.current + " times!"); } function handleClickState() { setState(state + 1); alert("You clicked " + state + " times!"); } return ( <> <button onClick={handleClick}>Click me!</button> <button onClick={handleClickState}>State Click me!</button> </> ); }
import { useRef } from 'react'; function MyComponent() { const inputRef = useRef(null); // ...
// ... return <input ref={inputRef} />;
function Video() { const playerRef = useRef(new VideoPlayer()); // ...
function Video() { const playerRef = useRef(null); if (playerRef.current === null) { playerRef.current = new VideoPlayer(); } // ...
useRef<T>(initialValue: T): MutableRefObject<T>;
useRef<T>(initialValue: T|null): RefObject<T>;
useRef<T = undefined>(): MutableRefObject<T | undefined>;
<Input inputRef={inputRef} />
<Input label="input 컴포넌트 분리" ref={inputRef} />
- ref는 예약어이므로 다른 props를 용어로 설정해 넘긴다. → 하지만 이는 ref가 많아질수록 다양한 이름이 등장할 가능성이 높다.
- 예약어인 ref를 이용해 넘겨준다.
- 이 방법은 forwardRef가 필요하다. forwardRef를 이용하면 ref를 이용해 넘길 수 있다.
- 대신 ref를 받는 자식 쪽에서는 다음과 같은 설정이 추가로 필요하다
import { forwardRef } from "react"; const Input = forwardRef(function Input( props: { label: string }, ref: React.ForwardedRef<HTMLInputElement>, ) { const { label } = props; return ( <div> <span>{label}</span> <input ref={ref} /> </div> ); }); export default Input;
React.RefObject<HTML 뭐시기>
가 아닌 위 예제처럼 React.ForwardRef<HTML 뭐시기>
로 선언해줘야 타입 에러가 발생하지 않는다