DOM에 refs 전달하기

  • 버튼이 하나 있다 가정해보자
function FancyButton(props) {
  return (
    <button className="FancyButton">
      {props.children}
    </button>
  );
}
  • 리액트 내부에서는 일반적인 방법으로 button에 대한 ref를 얻을 방법이 없다.
  • 일반적인 컴포넌트에서는 문제가 없지만, 이 버튼이 여러곳에서 재사용되게 된다면 이벤트 처리, 상태, 값 확인 등에서 DOM에 직접 접근하는게 불가피할 수도 있다.
  • 이런 상황에서 ref를 DOM에 전달해 직접적인 접근을 시도할 수 있다
  • React.forwardRef 문법을 사용해 ref 인자를 받아 사용을 할 수 있게 됨
// 재사용할 컴포넌트 prop에 ref 사용
// ref는 button DOM을 직접 가리킴
const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton"> 
    {props.children}
  </button>
));

// 재사용하는 버튼에 ref를 생성하고 컴포넌트에 전달
const ref = React.useRef(null);
<FancyButton ref={ref}>Click me!</FancyButton>;

고차원 컴포넌트에서의 ref 전달

function logProps(WrappedComponent) {
  const LogProps = (props) => {
    const prevProps = useRef();
    
    useEffect(() => {
      prevProps.current && console.log('old props:', prevProps.current);
      console.log('new props:', props);
      prevProps.current = props;
    }, [props]);
    
    return <WrappedComponent {...props} />;
  }
  return LogProps;
}

function FancyButton() {
  //...
}
export default logProps(FancyButton);
  • 다음과 같이 렌더링 되는 모든 prop을 기록하는 컴포넌트 함수가 있다 해보자.

  • 버튼에 전달되는 모든 컴포넌트는 기록되지만, 이 경우 ref는 prop이 아니기 떄문에 전달되지 않는다.

  • ref를 가져오기 위해 FancyButton에 ref를 추가한다고 해도 가장 바깥쪽 컴포넌트인 logProps를 참고하게 된다.

import FancyButton from './FancyButton';

// FancyButton컴포넌트가 아닌 LogProps를 가리킴
// 만약 ref.current.focus()를 한다 가정해도 이는 전달되지 않음
const ref = useRef(null);

<FancyButton
  label="Click Me"
  handleClick={handleClick}
  ref={ref}
/>;
  • FancyButton 컴포넌트 내부에 ref를 명시적으로 전달하기 위해서는 React.forwardRef API를 활용해야 함
  // 내부 컴포넌트에 forwardedRef를 속성을 전달해 직접적으로 컴포넌트 DOM 획득
const LogProps = (props) => {
  const prevProps = useRef();
    
  useEffect(() => {
    prevProps.current && console.log('old props:', prevProps.current);
    console.log('new props:', props);
    prevProps.current = props;
  }, [props]);
    
  const {forwardedRef, ...rest} = props;
  return <Component ref={forwardedRef} {...rest}/>;
}

// ref를 받아 forwardedRef와 같은 일반적인 속성으로 logProp에 전달
function logProps(WrappedComponent) {
  // props, ref을 받아 내부 컴포넌트에 대한 ref 전달
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}

출처:
https://ko.reactjs.org/docs/forwarding-refs.html

profile
냐아아아아아아아아앙

0개의 댓글

Powered by GraphCDN, the GraphQL CDN