코드도보통지

2관문. forwardRef & useImperativeHandle

관문 2 / 7

부모에게 DOM 전체 대신 focus()와 clear() 메서드만 노출하는 커스텀 Input을 만들어라.

📖 이론 비급

useImperativeHandle: 정제된 명령적 API

forwardRef로 ref를 받아 DOM 노드를 그대로 노출하면 부모가 input의 모든 속성에 접근할 수 있어 캡슐화가 깨진다.

useImperativeHandle(ref, () => ({ focus, clear }))를 사용하면 부모에게 명시적으로 허용한 메서드만 공개할 수 있다. 컴포넌트 API를 설계하듯 명령적 인터페이스를 제어하라.

⚔️ 수련 코드

import { useRef, forwardRef, useImperativeHandle } from 'react';

// TODO: forwardRef로 감싸고 useImperativeHandle을 사용하여
// focus()와 clear()만 노출하라
const FancyInput = forwardRef(function FancyInput(props, ref) {
  const inputRef = useRef(null);

  // useImperativeHandle(ref, () => ({
  //   focus: () => inputRef.current.focus(),
  //   clear: () => { inputRef.current.value = ''; },
  // }));

  return <input ref={inputRef} {...props} />;
});

export default function App() {
  const inputRef = useRef(null);
  return (
    <div>
      <FancyInput ref={inputRef} placeholder="입력..." />
      <button onClick={() => inputRef.current.focus()}>포커스</button>
      <button onClick={() => inputRef.current.clear()}>초기화</button>
    </div>
  );
}