forwardRef & useImperativeHandler 간단 정리

Lenny·2023년 12월 1일
0

forwardRef

사용자가 정의한 컴포넌트에 Ref를 전달하고 싶을때 사용합니다.

예시

사용자가 정의한 Input 컴포넌트가 다음과 같이 있을 때

const Input = (props) => {
  return (
    <div className={classes.input}>
      <label htmlFor={props.input.id}>{props.label}</label>
      <input {...props.input} />
    </div>
  );
};

이 컴포넌트를 사용하는 부모컴포넌트에서 이 컴포넌트의 input의 ref가 필요한 상황입니다!

import React, { useRef, useState } from 'react';
import Input from '../../UI/Input';
import classes from './MealItemForm.module.css';

const MealItemForm = (props) => {
  const amountInputRef = useRef();

  return (
    <form className={classes.form}>
      <Input
        ref={amountInputRef} ❗️❗️❗️❗️❗️❗️
        label='Amount'
        input={{
          id: 'amount_' + props.id,
          type: 'number',
          min: '1',
          max: '5',
          step: '1',
          defaultValue: '1',
        }}
      />
    </form>
  );
};

export default MealItemForm;

하지만 위 코드의 Input 컴포넌트의 ref를 얻을수가 없습니다. (사용자 정의 컴포넌트이기때문에, HTML 태그가 아님!)

위와 같은 상황일 때 ref를 얻기위해 사용합니다.

Input 컴포넌트를 다음과 같이 수정하면 부모 컴포넌트가 ref를 핸들링 할 수 있게됩니다.

import React from 'react';
import classes from './Input.module.css';

const Input = React.forwardRef((props, ref) => {
  return (
    <div className={classes.input}>
      <label htmlFor={props.input.id}>{props.label}</label>
      <input ref={ref} {...props.input} />
    </div>
  );
});

export default Input;

useImperativeHandler

useImperativeHandle은 ref를 사용할 때 부모 컴포넌트에 노출되는 인스턴스 값을 사용자화(customizes)합니다.

function ParentComponent() {
// 부모는 inputRef.current로 접근하여 자식의 메소드에 접근할 수 있습니다.
  const inputRef = useRef();
  return (
    <>
          <FancyInput ref={inputRef} />
          <button onClick={() => inputRef.current.realllyFocus()}>포커스</button>
    </>
  )
}
function FancyInput = React.forwardRef((props, ref) {
  // 부모는 이 로직에 대해 모르고, 위로 끌어올리지 않고도 그냥 ref.current로 접근하여 사용만 하면 된다
  const inputRef = useRef(null);
  useImperativeHandle(ref, () => ({
    reallyFocus: () => {
      inputRef.current.focus();
      console.log('Being focused!')
    }
  }));
  // ref는 input을 참조하고 있다. 
  return <input ref={inputRef} />
})

참조
https://velog.io/@whwkd11010/Ref-forwardRef-useImperativeHandle

profile
🧑‍💻

0개의 댓글