`useImperativeHandle`은 React Hook으로, 부모 컴포넌트에서 자식 컴포넌트의 특정 메서드나 속성을 직접 접근할 수 있게 해주는 기능입니다.
간단한 예제로 설명해드리겠습니다:
// 자식 컴포넌트
import React, { forwardRef, useImperativeHandle, useState } from 'react';
const ChildInput = forwardRef((props, ref) => {
const [value, setValue] = useState('');
// 부모에게 노출할 메서드들을 정의
useImperativeHandle(ref, () => ({
// 입력값을 초기화하는 메서드
clearInput: () => {
setValue('');
},
// 현재 입력값을 가져오는 메서드
getCurrentValue: () => {
return value;
},
// 입력값을 설정하는 메서드
setInputValue: (newValue) => {
setValue(newValue);
}
}));
return (
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
});
// 부모 컴포넌트
const ParentComponent = () => {
const childRef = useRef();
const handleClear = () => {
// 자식 컴포넌트의 메서드 호출
childRef.current.clearInput();
};
const handleGetValue = () => {
// 자식 컴포넌트의 현재 값 가져오기
const value = childRef.current.getCurrentValue();
console.log(value);
};
return (
<div>
<ChildInput ref={childRef} />
<button onClick={handleClear}>Clear</button>
<button onClick={handleGetValue}>Get Value</button>
</div>
);
};
주요 특징과 사용 시 주의점:
1. **제한된 사용**:
- 일반적인 React의 단방향 데이터 흐름을 해치므로 꼭 필요한 경우에만 사용해야 합니다.
- 대부분의 경우 props와 state로 해결할 수 있습니다.
2. **주요 사용 사례**:
- 외부 라이브러리와의 통합
- 복잡한 애니메이션 제어
- 폼 요소의 포커스/값 제어
- 미디어 요소(비디오, 오디오) 제어
3. **사용 방법**:
- `forwardRef`와 함께 사용해야 합니다.
- 첫 번째 인자로 ref를, 두 번째 인자로 노출할 객체를 반환하는 함수를 받습니다.
4. **성능 고려**:
- ref를 통한 직접 조작은 리렌더링을 발생시키지 않습니다.
- 필요한 메서드만 노출하여 불필요한 접근을 제한하는 것이 좋습니다.
// 실제 활용 예: 모달 컴포넌트
const Modal = forwardRef((props, ref) => {
const [isOpen, setIsOpen] = useState(false);
useImperativeHandle(ref, () => ({
open: () => setIsOpen(true),
close: () => setIsOpen(false),
isOpen: () => isOpen
}));
if (!isOpen) return null;
return (
<div className="modal">
{props.children}
<button onClick={() => setIsOpen(false)}>Close</button>
</div>
);
});
// 사용
const App = () => {
const modalRef = useRef();
return (
<div>
<button onClick={() => modalRef.current.open()}>Open Modal</button>
<Modal ref={modalRef}>
<h2>Modal Content</h2>
</Modal>
</div>
);
};
이런 식으로 모달, 폼, 캐러셀 등 복잡한 UI 컴포넌트를 제어할 때 유용하게 사용할 수 있습니다.