본문 바로가기
IT/react

React - useImperativeHandle 개념 잡기

by 내일은교양왕 2023. 10. 12.

useImperativeHandle에 대해 알아보자

 

딱봐서는 어떤 기능을 하는지 짐작하긴 힘들다.

Imperative에 대해 사전적 의미부터 살펴보자

 

Imperative 뜻은 '반드시 해야 하는' , '위엄 있는', '긴요한 것'으로 해석된다.

이런 뜻을 인지하면서 해당 hook이 어떤 기능을 하는지 알아보자

 

개념

`forwardRef`로 넘어간 ref instance를 이용하여 자식 컴포넌트 내의 기능을 부모 컴포넌트에서 직접 사용하고 싶을 때  사용하는 hook입니다. 

 

예시

App 컴포넌트

App 컴포넌트는 부모 컴포넌트이고 MyInput 컴포넌트는 하위 컴포넌트 입니다.

App 컴포넌트에서 ref값을 선언할때 어떤 기능을 담당하는지 Generic Type을 정의합니다.

MyInput 컴포넌트에 ref값을 넘겨줍니다.

focus 버튼을 클릭하면 ref에서 focus method를 실행합니다.

import React, { useRef } from 'react'
import ReactDOM from 'react-dom/client'

import { MyInput, RefMethod } from './MyInput'

const App = () => {
    const ref = useRef <RefMethod>(null)

    function handleClick() {
        ref.current?.focus()
    }
    return (
        <>
            <div>
                <button onClick={() => handleClick()}>focus</button>
            </div>
            <MyInput ref={ref} />
        </>
    )
}

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
)

 

MyInput

MyInput 컴포넌트는 forwardRef로 감싸져 있습니다.

useImperativeHandle를 선언하고 부모로 부터 받은 ref값을 첫번째 인자로 넣습니다.

두번째 인자로는 callback function이 들어가고 부모에게 어떤 기능을 넘겨줄지 명시합니다. 

현 구현으로는 2개가 선언되어 있네요.

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

export interface RefMethod {
    focus(options?: FocusOptions): void;
    scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
}
export const MyInput = forwardRef(function MyInput(props, ref) {
    const inputRef = useRef<HTMLInputElement>(null);

    useImperativeHandle(ref, () => {
        return {
            focus() {
                inputRef.current?.focus();
            },
            scrollIntoView() {
                inputRef.current?.scrollIntoView();
            },
        };
    }, []);

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

 

Real World Best Practices

개발자들은 언제 사용하는지 알아보겠습니다.

자식 컴포넌트에서 비디오 플레이어가 있고, 부모 컴포넌트에서 해당 플레이어를 재생, 멈춤, 건너뛰기를 해야할 수도 있습니다. 이때 useImperativeHandle를 사용하면 코드가 간단 명료해질 수 있습니다.

 

 

 

 

https://react.dev/reference/react/useImperativeHandle

 

useImperativeHandle – React

The library for web and native user interfaces

react.dev