[React forwardRef useImperativeHandle] 자식 컴포넌트 접근
❌ React 19에서는 더 이상 사용하지 않는다고 하고 ref 대신 prop로 전달하는 방법으로 안내하고 있습니다.
📌 forwardRef
- React에서 forwardRef는 부모 컴포넌트에서 자식 컴포넌트의 DOM 요소나 컴포넌트 인스턴스에 직접 접근할 수 있도록 도와주는 기능.
📍 필요한 이유
- 부모 컴포넌트가 자식 컴포넌트의 내부 DOM 요소에 직접 접근할 수 없지만 ref를 사용하면 DOM 요소에 접근할 수 있고, forwardRef를 활용하면 컴포넌트 간에 전달이 가능합니다!
✅ 사용 예
- focus() : 부모 컴포넌트에서 자식 컴포넌트의 input 요소에 포커스 이
- clear() : 입력 값을 지우는 메서드를 정의하여 부모에서 제어 가능하게 할 때
-scroll : 특정 요소로 스크롤 이동하도록 할 때
- 기타 등
📍 사용 방법
✅ forwardRef를 이용하여 부모 컴포넌트에서 자식 컴포넌트 접근
// ✅ TestPage.jsx -> Parent Component
import { useRef } from "react";
import { TistoryInput } from "./TistoryInput";
export const TestPage = () => {
const inputRef = useRef(null);
const focusInput = () => {
console.log(inputRef.current)
inputRef.current?.focus();
};
return(
<div className="test-wrap">
<TistoryInput ref={inputRef} placeholder="티스토리 input" />
<button
type="button"
onClick={focusInput}
>
<span>버튼</span>
</button>
</div>
)
}
// ✅ TistoryInput.jsx -> Child Component
import { forwardRef } from "react"
export const TistoryInput = forwardRef((props, ref) => { // forwardRef
return(
<input
type="text"
ref={ref}
{...props}
/>
)
});
✅ 버튼 클릭 시 input 에게 focus 이동
👆 console.log(inputRef.current) 확인 결과
📍 useImperativeHandle
useImperativeHandle은 forwarRef와 함께 사용되어 부모 컴포넌트가
자식 컴포넌트의 특정 메서드만 접근할 수 있도록 제한하는 역할을 수행하여
필요한 기능 사용으로 컴포넌트의 재사용성을 높일 수 있습니다 👍
📍 useImperativeHandle 사용 방법
// ✅ TestPage.jsx -> Parent Component
import { useRef } from "react";
import { TistoryInput } from "./TistoryInput";
export const TestPage = () => {
const inputRef = useRef(null);
const focusInput = () => {
console.log(inputRef.current)
inputRef.current?.focus();
};
const inputInit = () => {
inputRef.current?.init();
}
const inputError = () => {
inputRef.current?.error();
}
return(
<div className="test-wrap">
<TistoryInput ref={inputRef} placeholder="티스토리 input" />
<div className="btns">
<button
type="button"
onClick={focusInput}
>
<span>버튼</span>
</button>
<button
type="button"
onClick={inputInit}
>
<span>초기화</span>
</button>
<button
type="button"
onClick={inputError}
>
<span>Error</span>
</button>
</div>
</div>
)
}
import { forwardRef, useImperativeHandle, useRef, useState } from "react"
export const TistoryInput = forwardRef((props, ref) => {
const inputRef = useRef(null);
const [error, setError] = useState(false);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current?.focus()
},
init: () => {
inputRef.current.value = "";
setError(false);
},
error: () => {
inputRef.current.focus();
setError(true);
},
}));
return(
<div className="input-item">
<input
type="text"
ref={inputRef}
{...props}
className={error ? 'error': ''}
/>
{error && <p className="error-txt">Error</p>}
</div>
)
});
✅ 부모에서 input 컴포넌트에 접근하여 foucs, init, error 메서드를 호출할 수 있습니다.
👆 실행화면
foucs : 포커스
init: value 초기화, error state 변경
error : setState 변경, 포커스 이동
✅ 예제를 통해 상위 컴포넌트에서 원하는 동작을 쉽게 연결하여 사용할 수 있는 방법 확인!!
useImperativeHandle을 사용하여 편하게 동작도 가능하지만 useImperativeHandle 없이 props를 통해 직관적인 방법으로
필요한 기능을 전달하는 방법도 가능해요. 👍
✍️ 기록
감사합니다. 😁