forwardRef 사용하기

송현섭 ·2024년 7월 11일
0

개별공부

목록 보기
38/44



ref 오류


프로젝트 중, 커스텀 훅 내부에서 인자로 받아온 ref를 다시 return하는 다른 컴포넌트에 props로 전달해 줄 일이 있었다.


const renderCategorySelect = (isSub: boolean) => {
    return (
      <CustomSelect
        {...{
          ...SelectProps,
          onChange: handleCategoryChange,
          ref: isSub ? subRef : null,
          options: isSub
            ? copyOptionGroup.CategoryOptions[0].subCategory
            : copyOptionGroup.CategoryOptions,
        }}
      />
    );
  };
  • 해당 코드는 커스텀 훅 내부에 정의된 함수로, 지정한 커스텀 select 컴포넌트를 반환하는 데 이 때 내부 로직처리에 따라 정의된 기본 옵션들 또한 props 객체 형식으로 전달해 주고 있었다.

  • 문제는 여기서 ref 값도 할당해 주는 부분에서 에러가 발생했다.




  • 내용을 해석해 보자면 함수형 컴포넌트에서는 ref 라는 이름으로 props 속성같은 것을 전달할 수 없는 듯하다.
    클래스형과 달리 함수형에서는 인스턴스를 생성할 수 없기에 ref를 속성으로 사용할 수 없음!

  • 좀 더 찾아보니 ref는 DOM 참조를 위해 react 에서 내부적으로 사용되며, 이는 예약어이기 때문에 props로 전달할 때 ref 라는 이름값을 사용할 수 없다는 것이다.
    (속성으로 부여되는 key 같은 것과 비슷한 맥락)

  • 이에 대한 해결방안으로 에러에서 제안한 것처럼 forwardRef 를 사용해보기로 했다.




forwardRef 사용해보기


공식문서에 따르면 해당 ref를 전달받을 해당 컴포넌트를 forwardRef로 감쌎게 되면, 이 때 감싸진 컴포넌트 함수의 두번째 인자로 ref 객체를 전달받을 수 있다고 한다


 const renderCategorySelect = (isSub: boolean) => {
    return (
      <CustomSelect
        {...{
          ...SelectProps,
          onChange: handleCategoryChange,
          ref: isSub ? subRef : null,
          options: isSub
            ? copyOptionGroup.CategoryOptions[0].subCategory
            : copyOptionGroup.CategoryOptions,
        }}
      />
  • 앞서 코드와 똑같이 우선은 ref 속성을 전달해준다.




function CustomSelect(props, ref) {
  useImperativeHandle(ref, () => {
    customFocus: () => ref.current.focus();
  });

  return (
    <>
      <S.CustomSelector {...props} />
    </>
  );
}
export default forwardRef(CustomSelect);
  • ref를 전달 받는 컴포넌트 자체를 forwardRef로 감싸준다. 감싸준 이후부터는 이 컴포넌트 함수의 두번째 인자로 ref 객체를 그대로 전달받아 사용가능하다.

  • 추가로 useImperativeHandle 라는 react에서 자체 제공하는 함수를 이용해 ref 내부의 메서드를 사용자 정의(Customizing) 해줄 수도 있다.

profile
막 발걸음을 뗀 신입

0개의 댓글