React Native中基于Formik实现滚动至错误输入组件的方案咨询
基于Formik实现表单提交错误时自动滚动到第一个错误输入组件
针对大型表单提交出错后自动定位到错误输入的需求,你提供的代码可以进一步优化以提升可靠性和体验,以下是改进方案:
现有代码的问题
- 依赖
formik整个对象会导致useEffect频繁触发,因为Formik上下文对象每次渲染可能更新 - 判断条件依赖
isSubmitting(提交中状态)不准确,此时错误信息可能还未完成更新 - 通过
getFieldProps获取ref的方式兼容性较差,不适用于所有自定义输入组件
改进后的组件代码
import React, { useEffect } from 'react'; import { useFormikContext } from 'formik'; const ScrollToError = () => { const { errors, isSubmitting, submitCount } = useFormikContext(); useEffect(() => { // 仅在提交尝试完成且存在错误时执行 if (submitCount > 0 && !isSubmitting && Object.keys(errors).length > 0) { const firstErrorKey = Object.keys(errors)[0]; // 根据字段name查找对应输入元素(需确保表单元素name与Formik字段名一致) const errorElement = document.querySelector(`[name="${firstErrorKey}"]`); if (errorElement) { // 平滑滚动到错误元素并聚焦 errorElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); errorElement.focus(); } } }, [errors, isSubmitting, submitCount]); return null; }; export default ScrollToError;
关键优化点
- 用
submitCount判断是否有过提交尝试,避免组件初始化时误触发 - 依赖项仅保留必要属性(
errors、isSubmitting、submitCount),减少不必要的重渲染 - 通过
document.querySelector基于name属性查找元素,适配绝大多数原生/自定义输入组件 - 使用
scrollIntoView实现平滑滚动,同时聚焦错误输入,强化用户感知
使用方式
在Formik表单组件内部直接引入并渲染该组件即可:
import ScrollToError from './ScrollToError'; // Formik表单示例 <Formik initialValues={{ username: '', password: '' }} validationSchema={YourValidationSchema} onSubmit={(values) => { /* 提交逻辑 */ }} > {() => ( <Form> {/* 表单字段示例 */} <input name="username" type="text" /> <input name="password" type="password" /> {/* 自动滚动组件 */} <ScrollToError /> </Form> )} </Formik>
注意事项
- 确保所有表单输入组件的
name属性与Formik定义的字段名完全一致 - 若使用自定义输入组件,需将
name属性传递给底层的原生输入元素 - 可调整
scrollIntoView的参数(如block: 'start')来改变滚动位置
内容的提问来源于stack exchange,提问作者Jakub Kasprzyk
相关产品推荐
相关产品推荐

