코드노트

ref 여러개 하나의 ref로 관리, mergeRefs 함수 정리, feat, ForwardedRef 본문

Code note/리액트

ref 여러개 하나의 ref로 관리, mergeRefs 함수 정리, feat, ForwardedRef

코드노트 2024. 4. 18. 14:32

리액트를 하면서 useRef를 사용하며, 여러개의 Ref를 사용하게 된다면 어떻게 해야할까?

 

리액트 네이티브를 공부하면서 input을 컴포넌트로 관리하다가 Ref를 사용하여 다음 input으로 넘겨야했다.

하나의 refRef input컴포넌트 내에서 관리중이였고,

외부에서 컴포넌트에 Ref를 또 넘겨주어야했다.

Ref를 2개를 사용할 수는? 있다. ForwardedRef를 사용하자.

 

더군다나 타입스크립트로 작업중이라면 머리가 더 복잡해질 수 있지만 이번에 컴포넌트를 만들면서 어느정도의 개념이 잡힌것 같다.

 

 

mergeRefs 함수

function mergeRefs<T>(...refs: ForwardedRef<T>[]) {
  return (node: T) => {
    refs.forEach(ref => {
      if (ref && typeof ref !== 'function') {
        ref.current = node;
      }
    });
  };
}

- 제네릭타입으로 T는 Ref가 참조하는 DOM의 타입이다.

- rest로 여러개의 ref를 받게 된다. 

- forEach를 순회하면서 Ref.current에 node값을 설정하여 실제 DOM요소에 대한 참조를 설정한다.

이렇게 다수의 ref가 동일한 DOM요소를 가리키게 하여 하나의 Ref로 결합할 수 있게 할 수 있다.

 

이렇게 하면 여러개의 Ref가 하나의 Ref로 결합되고 해당 Ref를 통해서 실제 DOM요소에 쉽게 접근할 수 있다.

 

 

input 컴포넌트

const InputField = forwardRef(
  (
    {disabled = false, error, touched, ...props}: InputFieldProps,
    ref?: ForwardedRef<TextInput>,
  ) => {
    const innerRef = useRef<TextInput | null>(null);
    const handlePressInput = () => {
      innerRef.current?.focus();
    };
    return (
      <Pressable onPress={handlePressInput}>
        <View
          style={[
            ...
          ]}>
          <TextInput
            ref={ref ? mergeRefs(innerRef, ref) : innerRef}
            ...
          />
          {touched && Boolean(error) && (
            ...
          )}
        </View>
      </Pressable>
    );
  },
);

- 간단하게 코드를 줄여봤다. 우선 Ref를 props로 받는다.

- 코드에서 보이듯 컴포넌트 내부에서는 innerRef로 현재 Ref를 사용중이다.

- props로 받은 Ref가 있다면 mergeRefs함수를 통해서 여러개의 Ref가 접근할 수 있도록 할 수 있다.

 

 

현재는 DOM에 대한 Ref만 연결시켰지만 function을 연결한다거나 추가적으로 실행할 수도 있다.

function mergeRefs<T>(...refs: ForwardedRef<T>[]) {
  return (node: T) => {
    refs.forEach(ref => {
      if (typeof ref === 'function') {
        ref(node);
      } else if (ref) {
        ref.current = node;
      }
    });
  };
}

 

 

 

 

merge-refs

A function that merges React refs into one.. Latest version: 1.2.2, last published: 6 months ago. Start using merge-refs in your project by running `npm i merge-refs`. There are 52 other projects in the npm registry using merge-refs.

www.npmjs.com

라이브러리도 있으니 참고하면 좋을것 같다.