보통 ref를 통해서 DOM요소들에 접근하고 제어하지만 컴포넌트가 크다보면 컴포넌트를 나눠야 할 경우가 생깁니다.
이때 상위 컴포넌트에서 하위 컴포넌트의 DOM요소를 제어하고 싶은데 ref를 props로 넘기면 에러가 발생하게 됩니다. 상위 컴포넌트로 ref를 넘기는 것도 할 수 없는 일입니다.
이때 하위 컴포넌트로 ref 를 넘기기 위해 Forward Refs
라는 개념이 사용되게 됩니다. 하위 컴포넌트에서 ref 를 받을 수도 없는데 ref는 일종의 예약어
이기 때문입니다.
우리는 이를 위해서 두가지를 해야합니다.
먼저 하위컴포넌트에 useImperativeHandle
훅을 가져와야합니다.
첫번째 인수는 상위 컴포넌트로 부터 받는 props 말고 ref라는 인수를 추가로 받아서 props와 구분하는 ref를 받습니다.
이렇게 하기 위해서 우리는
React.forwardRef
라는 함수로 컴포넌트 호출부 전체를 감싸줍니다. 그러면 컴포넌트는 상위에서 오는 ref를 받을수 있습니다. forwardRef는 리액트 컴포넌트를 반환하는데, ref가 바인딩된 리액트 컴포넌트를 반환해줍니다.
다음으로 해당 ref로 접근가능한 내부 동작을 호출해야하는데, 이는 useImperativeHanle
에서 사용하는 두번째 인수로서의 콜백에서 설정가능합니다.
두번째 인수에서의 콜백에서 우리는 상위 컴포넌트에서 ref.current로 접근가능한 프로퍼티의 이름 (위 코드에서는 focus) 과 해당 이름으로 자식 컴포넌트에서 조작할 함수
를 입력합니다.
useImperativeHanle(ref, ()=>{return {외부프로퍼티이름: 내부함수}})
이러한 형태입니다.
위코드를 보면 상위 컴포넌트에서 ref.current.focus()
를 사용하면 자식컴포넌트의 activate
함수를 알맞게 실행한다는 의미가 됩니다.
기본적으로 자식컴포넌트의 특정 기능이나 값을 부모컴포넌트로 노출시킬수 있다는 점에서는 위 기능을 사용할수 있습니다. 하지만 값을 노출시키는 것은 피해야합니다. 리렌더링 과정에서 ref는 제대로된 기능을 할수 없습니다. 하지만 위와같은 focusing
,scrolling
과 같은 방식에 있어서 매우 실전적이고 유용하게 사용이 가능합니다.