当我的所有复选框输入都具有相同名称时,如何滚动到第一个错误?

问题描述 投票:0回答:1

我正在使用 React 18、Ionic 7 和 Formik 2.4.3。当我想滚动到错误位置的顶部时,我使用一个组件

export const getFieldErrorNames = (formikErrors) => {
  const transformObjectToDotNotation = (obj, prefix = '', result = []) => {
    Object.keys(obj).forEach((key) => {
      const value = obj[key]
      if (!value) return

      const nextKey = prefix ? `${prefix}.${key}` : key
      if (typeof value === 'object') {
        transformObjectToDotNotation(value, nextKey, result)
      } else {
        result.push(nextKey)
      }
    })

    return result
  }

  return transformObjectToDotNotation(formikErrors)
}

const ScrollToFieldError = ({ submitCount, errors }) => {
  useEffect(() => {
    const fieldErrorNames = getFieldErrorNames(errors)
    if (fieldErrorNames.length <= 0) return

    const elements = document.getElementsByName(fieldErrorNames[0])
    const element = elements[0]
    if (!element) return

    // Scroll to first known error into view
    element.scrollIntoView({ behavior: 'smooth', block: 'center' })
  }, [submitCount])

  return null
}

export default ScrollToFieldError

在我的 Formik 表单中,我像这样使用组件

  const validationSchema = Yup.object().shape({
    selectedIds: Yup.array().min(1, 'Select at least one item').required('Select at least one item')
  })
    ...

    <Formik
      enableReinitialize={true}
      initialValues={{ selectedIds }}
      validationSchema={validationSchema}
      onSubmit={(values) => {
        handleSaveAndContinue(values.selectedIds)
      }}
    >
      {(formikProps) => (
        <form onSubmit={formikProps.handleSubmit}>
          <ScrollToFirstError submitCount={formikProps.submitCount} errors={formikProps.errors} />
          {formikProps.touched.selectedIds && formikProps.errors.selectedIds ? (
            <div>{formikProps.errors.selectedIds}</div>
          ) : null}
          <IonList>
            ...
            {items.map((item) => (
              <IonItem key={item.id}>
                <IonCheckbox
                  name='selectedIds'
                  value={item.id}
                  
                >{`${item.name}`}</IonCheckbox>
              </IonItem>
            ))}
          </IonList>
          <IonButton aria-lael='Save And COntinue' type='submit'>
            Submit
          </IonButton>
        </form>
      )}
    </Formik>

问题是,当我单击“提交”按钮而不检查任何内容时,尽管我的错误消息正确显示,但不会滚动到页面顶部。我想让我的组件 ScrollToFirstError 尽可能通用,因为我在其他类型的表单上使用它,所以很好奇是否有一种方法可以调整我现有的表单以使功能正常工作。有问题的示例在这里 - https://stackblitz.com/edit/an5yjh-c2pz8v?file=src%2Fcomponents%2FScrollToFirstError.tsx,src%2Fcomponents%2FMyForm.tsx,package-lock.json

reactjs checkbox scroll formik ionic7
1个回答
0
投票

看来

formikProps.submitCount
formikProps.errors
的值是分别更新的。他们不会同时更新。
ScrollToFieldError
的useEffect仅具有
submitCount
的依赖性,而不具有
errors
的依赖性。因此,当它检测到提交更改时,错误数组尚未更新。在依赖项中添加
errors
将解决您的问题。

const ScrollToFieldError = ({ submitCount, errors }) => {
  useEffect(() => {
    const fieldErrorNames = getFieldErrorNames(errors);
    if (fieldErrorNames.length <= 0) return;

    const elements = document.getElementsByName(fieldErrorNames[0]);
    const element = elements[0];
    if (!element) return;

    // Scroll to first known error into view
    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }, [submitCount, errors]);

  return null;
};
© www.soinside.com 2019 - 2024. All rights reserved.