일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 자바스크립트
- next13
- stack문제
- 자바스크립트코딩테스트
- 제로베이스
- JavaScript
- leetcode
- 알고리즘문제풀이
- lodash
- 자바스크립트 알고리즘
- 자바스크립트 문제
- 리액트
- JS
- til
- 리액트쿼리
- CSS
- Next
- 자바스크립트 문제풀이
- 프론트엔드
- 프로그래머스
- NPM
- 자바스크립트 문제 풀이
- 타입스크립트
- Next.js13
- 자바스크립트 연결리스트
- HTML
- Baekjoon
- leetcode문제풀이
- 자바스크립트 알고리즘 문제
- react
- Today
- Total
코드노트
ref 여러개 하나의 ref로 관리, mergeRefs 함수 정리, feat, ForwardedRef 본문
리액트를 하면서 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;
}
});
};
}
라이브러리도 있으니 참고하면 좋을것 같다.
'Code note > 리액트' 카테고리의 다른 글
리액트 네이티브 절대 경로 지정 Feat. babel (0) | 2024.04.20 |
---|---|
리액트 네이티브 TextInput 기능 정리, RN (0) | 2024.04.17 |
리액트쿼리를 쓴다면 이건 꼭 알고 쓰자 (0) | 2024.03.20 |
리액트 가상돔 Virtual DOM 정리 (0) | 2023.08.04 |
리액트 createPortal로 DOM추가하기 (0) | 2023.08.01 |