React.forwardRef

huewilliams·2021년 8월 25일
0
post-thumbnail

회사에서든 집에서든 개발을 하다 보면 모르는 개념이 많이 생긴다. 실제로 사용하고는 있지만 그 원리를 모르면 모르는 것과 마찬가지이기 때문에 매일 모르는 부분을 하나씩 없애간다는 생각으로 궁금증을 하나씩 해결해나가려고 한다. 오늘이 그 시작이다.

배경

최근 Slate 라이브러리(https://github.com/ianstormtaylor/slate)를 사용하기 위해 예제 코드와 공식 문서를 둘러보던 중 React.forwardRef()를 사용한 코드들이 많이 있었다.

// slate 예제 코드 (https://github.com/ianstormtaylor/slate/blob/main/site/components.tsx)
export const Icon = React.forwardRef(
  (
    { className, ...props }: PropsWithChildren<BaseProps>,
    ref: Ref<OrNull<HTMLSpanElement>>
  ) => (
    <span
      {...props}
      ref={ref}
      className={cx(
        'material-icons',
        className,
        css`
          font-size: 18px;
          vertical-align: text-bottom;
        `
      )}
    />
  )
)

코드 사용을 봤을 때 Ref를 컴포넌트에 전달해주는 용도로 쓰고 있는 것임을 얼추 알 수 있었지만, 이렇게 막연하게 넘어가면 발전이 없기 때문에 자세히 공부해보기로 결정했다.

학습(Reference)

가장 좋은 레퍼런스인 리액트 공식 문서로 ref 개념을 복습했다. (https://ko.reactjs.org/docs/refs-and-the-dom.html)
forwardRef()는 블로그를 통해 배웠다. (https://www.daleseo.com/react-forward-ref/)
기존에 Ref를 사용하는 방법으로 React.createRef()useRef hook 방식을 주로 사용했는데, 새로운 Ref를 다루는 방식을 하나 더 배우게된 것 같다.

정리

Ref

Ref는 render 메서드 내부의 DOM 노드나 React 엘리먼트에 접근할 수 있는 방법을 제공한다.
DOM 노드의 HTML 요소를 직접다루기 위해서 사용되기도 하고, 컴포넌트에 ref를달아 컴포넌트 내부의 메서드 및 멤버 변수(주로 다른 컴포넌트 내부의 HTML element 접근 용도)에 접근할 수 있다. 다만 특수한 경우를 제외하고 컴포넌트에 ref를 달아서 다른 컴포넌트로 전달하는 방식은 부모에서 자식으로 흘러가는 React의 데이터 흐름에 위배될 수 있기 때문에 사용하기전에 고민이 필요하다.

React.fowardRef()

React에서는 특수한 목적으로 사용되기 때문에 일반적인 용도로 사용하지 못하는 props이 몇 가지 존재한다. ref prop은 HTML 엘리먼트 접근이라는 특수한 용도로 사용되므로 일반적인 prop으로 사용할 수 없다.

HTML 엘리먼트가 아닌 React 컴포넌트에서 ref prop을 사용하려면 React에서 제공하는 forwardRef() 함수를 사용해야 한다. React 컴포넌트를 forwardRef() 함수로 감싸면 두 번째 매개변수로 ref를 전달받기 때문에, 이를 통해 외부에서 ref prop을 넘길 수 있다.

import React, { forwardRef, useRef } from react;

const Input = forwardRef((props, ref) => {
    return <input ref={ref}/>
});

function Field() {
    const inputRef = useRef(null);
    
    function handleFocus() {
    	inputRef.current.focus();
    }
    
    return (
      <>
        <Input ref={inputRef}/>
        <button onClick={handleFocus}>입력란 포커스</button>
      <>
  )
}

지금까지 Ref 개념을 복습하고 forwardRef를 사용하는 이유와 사용법을 알아보았다. 확실히 함수의 존재 이유와 사용법을 제대로 알게되니 후련하고 더욱 이해도가 높아진 것 같다. 앞으로도 모르는 개념이 있다면 확실하게 알고 넘어가야 겠다.

0개의 댓글