사내에서 사용할 UI 라이브러리를 만들면서 다른 UI 라이브러리들의 내부를 분석하였는데 공통적으로 쓰이고 있는 forwardRef() 에 대해서 궁금증을 갖고 알아보게 되었습니다.
# Ref
ref 는 참조라는 뜻을 갖고 있습니다. 우선 리액트에서 사용되는 Ref 에 대해서 알아보았습니다.
Ref 는 render 메서드에서 생성된 DOM 노드나 React 엘리먼트에 접근하는 방법을 제공합니다.
리액트에서는 props 를 통해서 부모에서 자식으로 단방향으로 데이터를 내려주고 있습니다. 자식 컴포넌트가 수정되기를 원한다면 새로운 props 를 전달하여 리렌더링을 통해 수정을 할 수 있습니다. 그러나 가끔 직접 자식을 수정해야 할 경우가 있을 수 있습니다.
리액트 공식문서에서 Ref 를 사용해야하는 바람직한 사례를 세가지를 들고 있습니다.
- 포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할때
- 애니메이션을 직접적으로 실행시킬때
- 서드파티 DOM 라이브러리를 React 와 같이 사용할때
그리고 사용하지 말아야하는경우 지양해야 하는 경우도 있습니다.
- 선언적으로 해결될 수 있는 문제에 대해서는 ref 사용을 지양
React는 선언적 프로그래밍으로 만들어 졌기때문에 돔에 접근하여 돔을 업데이트하는 세부적인 사항에 대해서는 사용자가 신경쓰지 않아도 되도록 구현되어 있습니다. 그런 간혹 돔에 직접 접근이 필요한 경우가 있는데 이때 ref 를 사용하여 접근할 수 있습니다.
리액트 16.3 이후부터는 React.createRef() API 를 사용할 수 있고 이전 버전에서는 콜백 ref 를 사용해야 합니다.
리액트는 클래스컴포넌트와 함수컴포넌트 두가지로 작성할 수 있는데 최근 트랜드는 함수컴포넌트를 쓰고 있습니다. 클래스와 다르게 함수는 인스턴스가 없기 때문에 함수컴포넌트에 직접적으로 ref 속성을 사용할 수 없습니다. 그래서 이때 사용할 수 있는 방법이 forwardRef() 라는 함수 입니다.
# forwardRef()
리액트 컴포넌트를 forwardRef() 라는 함수로 감싸게되면 해당 컴포넌트는 두번째 매개변수를 갖습니다. 이를 통해 외부에서 ref props 을 전달하여 사용할 수 있습니다.
정리하자면 forwardRef() 는 기존 클래스 컴포넌트에서 인스턴스를 활용하여 사용하던 ref 속성을 함수컴포넌트에서는 사용이 불가능하기때문에 외부로 ref 를 전달할 수 있도록 해주는 함수 입니다.
forwardRef() 를 사용했을경우 리액트 개발자 도구에서 컴포넌트 이름이 노출되지 않을 수 있기때문에 이를 해결하기위해 아래와 같은 방법을 사용할 수 있습니다.
## material-ui 에서 사용중인 방법
forwardRef() 로 감쌀때 익명함수가 아닌 이름이 있는 함수를 넘겨주는 방법입니다.
const Input = React.forwardRef(( function Input(props, ref) {} ))
## chakra-ui 에서 사용중인 방법
displayName 속성에 이름을 설정합니다.
export const Input = forwardRef((props, ref) => {...})
if (__DEV__) {
Input.displayName = "Input"
}
## ant-design 에서 사용중인 방법
forwardRef() 함수의 호출 결과로 기존 컴포넌트 대체하기
// ==== Input ======//
const Input = forwardRef((props, ref) => {...})
export default Input
//====== index ========//
import InternalInput from './Input'
const Input = InternalInput
export default Input
'프론트엔드 > React' 카테고리의 다른 글
React Lifecycle - class & hook 2부 (0) | 2021.12.17 |
---|---|
React Lifecycle - class & hook 1부 (0) | 2021.12.16 |
React 동작 이해하기 (0) | 2021.10.18 |