Safari on iOS/Firefox 를 완벽하게 지원하는 React Hook Form
16418 단어 ReactTypeScripttech
2021/11/26 업데이트
하고 싶은 일: 검증 오류가 발견되면 오류 원인을 표시하고 싶은 input 요소
유효성 검사 오류가 발견되면 다음을 수행합니다.
질문: 크롬은 OK지만 Safari on iOS와 Firefox는 NG입니다.
Safari on iOS와 라디오/checkbox에서 오류가 발생했을 때 화면 스크롤에는 동작이 없습니다.
인풋 요소는 화면 밖에서 오류 메시지를 볼 수 없다며 "발송 버튼을 누르면 작동하지 않는다! 이유도 분명하지 않다!"이러면 곤란해.
재현 환경을 만들었으니 관심 있는 사람은 해보세요.
Firefox 스크롤이 충분하지 않습니다.인풋 요소의 하부가 은근히 보이는 정도입니다.
2021/11/24 현재 검증된 최신 환경
이유: HTML InputElementfocus () 의 동작은 브라우저에 따라 다릅니다
react-hook-form에서 오류가 발생한 원인은 Input 요소의 focus ()입니다.그러나 사파리(iPhone/iPad)의 라디오/checkbox는 포커스()라고 불러도 화면을 굴리지 않는다.
참조: https://stackoverflow.com/questions/56137175/ios-safari-chrome-wont-scroll-up-to-show-validation-error-message-on-radio-inpu
(자세가 너무 길어서 한 화면으로 줄이는 게 좋을 것 같은데...)
대책: onFocus에서 scrollIntoView () 를 실행한 후 화면 스크롤
input의 패키지 구성 요소 을 만들었습니다. 대상 요소가focus 이벤트가 발생할 때scrollIntoView () 스크롤 화면을 실행합니다.
input 패키지 구성 요소 만들기
Input.tsx
type InputProps = React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>;
const Input = React.forwardRef<HTMLInputElement, InputProps>(
(props, ref) => {
const onFocus: FocusEventHandler<HTMLInputElement> = (event) => {
// バリデーションエラー発生時にradio/checkboxのinputにしっかりスクロールしない問題のワークアラウンド
// 【問題詳細】
// Safari on iOS: 全くスクロールしない, FireFox,IE:スクロールが不十分でエラーメッセージが見えない,
if (props.type !== "radio" && props.type !== "checkbox") {
return;
}
try {
const element = event.currentTarget;
// radio/checkboxをタップしたときはスクロールしない
if (isInviewAll(element)) return;
// バリデーションエラー発生時のみスクロールする
// 注意:本対応はIE対応できていない(scrollIntoViewはIE非対応)
element.scrollIntoView({
block: "center",
behavior: "auto",
});
} catch (e) {
console.error(e);
}
};
return <input ref={ref} onFocus={onFocus} {...props} />;
}
);
const isInviewAll = (element: HTMLInputElement) => {
const rect = element.getBoundingClientRect();
// 1 < rect.top は firefox対応
return 1 < rect.top && rect.bottom < window.innerHeight;
};
Input.displayName = "Input";
export default Input;
react-hook-form의 공식 수첩을 참고하여 포장 부품을 제작하였습니다.사용 예: 제작된 <Input>은 <input>와 같이 사용할 수 있습니다
sample.tsx
const {
register,
formState: { errors },
handleSubmit,
} = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<p>Q1. 好きなプログラミング言語はなんですか?</p>
{errors?.language && (
<p className="text-red-500 py-2 px-2">
<span>選択してください</span>
</p>
)}
<Input
type="radio"
value="TypeScript"
{...register("language", { required: true })}
/>
<label>TypeScript</label>
<button
type="submit"
className="text-white bg-blue-600 py-2 px-4 rounded-md"
>
送信
</button>
</div>
</form>
);
끝말
이것은 이번에 만든 소스 코드다.
더 좋은 방법이 있으니까 댓글과 MR을 받으면 기쁠 거예요!
Reference
이 문제에 관하여(Safari on iOS/Firefox 를 완벽하게 지원하는 React Hook Form), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/daisuke7924/articles/5839e0094c5fdf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)