react native 공부를 하며 회원가입과 로그인의 form
작업을 진행중이다.
// InputField 컴포넌트
const innerRef = useRef<TextInput | null>(null);
const handlePressInput = () => {
innerRef.current?.focus()
}
<Pressable onPress={handlePressInput}>
<TextInput
ref={innerRef}
/>
{error && <Text style={styles.error}>{error}</Text>} // error 영역
</Pressable>
const passwordRef = useRef<TextInput | null>(null);
<InputField
returnKeyType="next"
blurOnSubmit={false}
onSubmitEditing={()=> passwordRef.current?.focus()}
placeholder="이메일"
/>
<InputField ref={passwordRef} placeholder="비밀번호" /> // 해당 컴포넌트는 이미 내부에 ref가 존재
이메일
을 입력하고 비밀번호
로 이동할때 next
를 누르면 비밀번호
로 이동하도록 했다.
이미 <Pressble />
을 이용해 ref
를 사용하고 있어, 두개의 ref
를 사용해야한다.
순서는 아래와 같다.
<inputField/>
를forwardRef
로 감싸준다.- 외부에서 받은
ref(파라미터)
, 내부의ref(로컬)
를 병합한다.
import React, { ForwardedRef, forwardRef, useRef } from "react";
import { Dimensions, StyleSheet, TextInput, View, TextInputProps, Text, Pressable } from "react-native";
const InputField = forwardRef(({ ...props }, ref: ForwardedRef<TextInput>) => { // 외부 ref
const innerRef = useRef<TextInput | null>(null); // 내부 ref
const handlePressInput = () => {
innerRef.current?.focus()
}
return (
<Pressable onPress={handlePressInput}>
<TextInput
ref={ref ? mergeRefs(innerRef, ref) : innerRef} // ref 병합 진행
/>
</Pressable>
)
});
// mergeRefs
import { ForwardedRef } from "react"; // refs의 타입을 받는다.
function mergeRefs<T>(...refs: ForwardedRef<T>[]) { //ForwardedRef은 다수를 받도록 리스트로 받음.
return (node: T) => {// return node는 dom요소나 react 컴포넌트 이다.
refs.forEach(ref => {// 순회하며, 함수인지 객체인지 확인한다.
if (typeof ref === 'function') {
ref(node)
} else if (ref) {
ref.current = node;
}
})
}
}
export {mergeRefs}
이로써, 포커스 이동과 TextInput영역 클릭 ref 둘다 사용할 수 있다.