React.forwardRef

유의진·2024년 12월 3일
0
post-thumbnail

forwardRef 란

컴포넌트가 ref를 받아 하위 컴포넌트로 전달하도록하려면 forwardRef를 사용해야한다.

예시 코드

import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
  // ...
});

사용법 (Input)

ex) inputfocus할 때 사용하는 방법

Edit 버튼을 클릭하면 자동으로 input에 focus된다

import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}


주의점

ref를 과도하게 사용하지 마세요. 노드로 스크롤 하기, 노드에 포커스하기, 애니메이션 트리거하기, 텍스트 선택하기 등 prop로 표현할 수 없는 필수적인 동작에만 ref를 사용해야 합니다.
prop로 무언가를 표현할 수 있다면 ref를 사용해서는 안 됩니다. 예를 들어 Modal 컴포넌트에서 { open, close }와 같은 명령형 핸들을 노출하는 대신 <Modal isOpen={isOpen} />과 같이 prop isOpen을 사용하는 것이 더 좋습니다. Effects는 props를 통해 명령형 동작을 노출하는 데 도움이 될 수 있습니다.
https://ko.react.dev/reference/react/forwardRef#usage



커스텀 Input

현재 Input 컴포넌트를 만들 때 forwardRef를 사용해서 ref를 받아올 수 있는 Input으로 만들었다.

import { forwardRef } from 'react';

import { cn } from '@/utils/className';

export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;

export const Input = forwardRef<HTMLInputElement, InputProps>(
  ({ className, type = 'text', ...props }, ref) => {
    const inputClass = cn(
      'w-full px-24 py-12 outline-none bg-white rounded-12 text-sm-normal md:text-base-normal',
      className,
    );

    return <input ref={ref} type={type} className={inputClass} {...props} />;
  },
);

Input.displayName = 'Input';

이때 Input.displayName을 지정해야하는 이유는

eslint-plugin-react 에서 Component definition is missing display name 에러를 내준다.

이 컴포넌트의 이름이 있어야하는데 export로만 반환하면 이름이 지정되어있지 않아서 나타내는 에러이다.

해결 방법
1. export default로 반환
2. displayName으로 이름 지정



참고

React 공식문서 (한글)
https://ko.react.dev/reference/react/forwardRef#usage

Component definition is missing display name 에러
https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md

profile
안녕하세요. 프론트엔드 개발 공부를 하고 있습니다.

0개의 댓글

관련 채용 정보