일반 ref와 forwardRef의 차이를 알아보자
ref는 보통 포커스나 스크롤이벤트 등 가상 돔을 패스하고 직접 내가 돔노드에 접근하고 싶을 때 쓴다.
그럼 forwardRef는 어떤 상황에서 써야 하나?
부모 컴포넌트에서 자식 컴포넌트로 ref 를 전달할때 쓴다. ( 이때 ref 는 자식 컴포넌트를 가리키고 있는 상태가 됨 )
그냥 ref 를 전달하면 되는거 아닌가? 라고 생각했지만,
ref는 리액트 내부적으로 만든 특수한 프로퍼티이기 때문에 그냥 컴포넌트간 전달이 막혀있다.
( console.log()에 찍으면 undefined가 뜸 )
forwardRef는 컴포넌트간 전달을 할수 있도록 만들어져있다. 그래서 부모 컴포넌트에서 자식 컴포넌트의 돔에 직접 접근할때 사용할 수 있는것이다.
사용 방법은 다음과 같다.
< useRef >
import {CustomInput} from "../customInput.jsx";
function App(){
const ref = useRef(null);
return (
<>
<input ref={ref}/> // 이건 가능. ref가 가리키는건 input 돔
<CustomInput ref={ref}/> // 이건 불가능.
// CustomInput 에서 prop 으로 받아와도 undefined가 찍힌다
</>
)
}
...
export function CustomInput({ref}){
console.log(ref); // =undefined
return <input/>
}
< forwardRef >
import {CustomInput} from "../customInput.jsx";
function App(){
const ref = useRef(null);
return (
<>
<CustomInput ref={ref}/> // 이렇게 사용하고 ref가 가리키는 돔은 CustomInput의 input
</>
)
}
...
export const CustomInput =forwardRef((props, ref)=>{
return <input ref={ref}/>
})
+ useInperativeHandle
forwardRef와 함께 쓰이는 고급 기능.
이걸 사용하면 자식컴포넌트 내부에서 정의된 함수중 특정 함수만 외부에서 사용할수 있도록 제어할 수 있다.
기존에는 부모 컴포넌트에서 함수를 만들고 이걸 자식 컴포넌트에서 넘겨 받아서 사용하는데,
이렇게 되면 불필요한 리렌더링이 발생할 수 있다.
리렌더가 일어나는 이유는 총 세가지인데 챗지피티에 따르면 하위 표와 같다.
| props 변경 | React의 렌더링 데이터 변경 | ✅ 발생 |
| state 변경 | React의 렌더링 데이터 변경 | ✅ 발생 |
| 부모 렌더링 | Virtual DOM 재비교 필요 | ✅ 발생 |
그런데 useInperativeHandle로 정의된 함수는
ref.current.method() 호출 -> JS 레퍼런스 호출이기 때문에 React와는 무관하고 따라서 리렌더가 발생하지 않고 함수만 호출하게 되는것.
즉, useImperativeHandle의 진짜 의의는?
단순히 부모가 자식 함수 “호출 가능”하게 해주는 게 아니라,
그 호출이 React 렌더 사이클에 영향을 주지 않고 독립적으로 동작하도록 하는 것이다.
그래서 useImperativeHandle을 통해 만든 API는
렌더를 발생시키지 않으면서 컴포넌트의 내부 동작만 수행할 수 있다.
(대표 예: .focus(), .open(), .close())
사용법은
import { forwardRef, useImperativeHandle, useRef } from "react";
const CustomInput = forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus(),
clear: () => (inputRef.current.value = "")
}));
return <input ref={inputRef} />;
});
function App() {
const ref = useRef();
return (
<>
<CustomInput ref={ref} />
<button onClick={() => ref.current.focus()}>포커스</button>
<button onClick={() => ref.current.clear()}>초기화</button>
</>
);
}
이런식으로 사용하면 된다
'React.js' 카테고리의 다른 글
| react state update & call api in a method with new state (3) | 2025.07.09 |
|---|---|
| setState를 했는데 바로 직전 상태값이 나와요 (5) | 2025.06.20 |
| [React] MUI (Material-UI) 이용한 리액트 화면 디자인 (0) | 2022.04.13 |
| [react] react hooks 실습 - 진행중 (0) | 2022.01.21 |
| [1128] react CopyToClipboard - 클릭시 텍스트 복사하기 (0) | 2021.11.29 |