停止handleBlur做任何事情

问题描述

在我的Formik表单中,当我单击搜索按钮时,将显示项目列表(UsersFoundList)。此列表在表单外部,并且列表中的每个项目都有其自己的按钮。

当我第一次单击列表中的任何按钮时,它们将不起作用。相反,会触发我的表单的handleBlur ,并且由于输入字段为空,因此错误消息开始在输入字段下方显示。因此,该按钮没有执行第一次尝试时应执行的操作。我通过将控制台日志写入其中来测试handleBlur。

仅当我尝试再次提交表单时,才会出现此错误。当我单击其他任何东西时都不会。

const [showFlatList,setShowFlatList] = useState(false);

    const handleSubmitForm = (
    values: FormValues,helpers: FormikHelpers<FormValues>,) => {
    console.log('hello',values.input)
    setShowFlatList(true);
    helpers.resetForm();
  };
  return (
    <View style={styles.container}>
      <View >
          <Formik
            initialValues={initialValues}
            onSubmit={handleSubmitForm}
            validationSchema={addRelationValidationSchema}>
            {({ handleChange,handleBlur,handleSubmit,values }) => (
              <View style={styles.searchFieldContainer}>
                <View style={styles.form}>
                  <FieldInput
                    handleChange={handleChange}
                    handleBlur={handleBlur}
                    value={values.input}
                    fieldType="input"
                    icon="user"
                    placeholderText="E-Mail oder Telefonnummer oder Name"
                  />
                  <ErrorMessage
                    name="input"
                    render={(msg) => <ErrorText errorMessage={msg} />}
                  />
                </View>
                <View style={styles.buttonContainer}>
                  <NewButton buttonText="Suchen" onPress={handleSubmit} />
                </View>
              </View>
            )}
          </Formik>
        </View>
                <View style={styles.listHolder}>
          {showFlatList && (
            <UsersFoundList/>
          )}
        </View>
    </View>
  );

如果在电话上运行 codesandBox ,您会看到问题:

https://snack.expo.io/@nhammad/jealous-beef-jerky

我需要停止handleBlur做任何事情。如果我单击列表中的a按钮,则它应该在第一次尝试时起作用,而不是触发handleBlur。即使我添加validateOnBlur=false,问题仍然存在。在这种情况下,错误消息不会显示,但在第一次尝试时该按钮仍然无法使用。

我单击的按钮具有单独的功能。并且此按钮在表单外部,因此它应该执行原本应该执行的操作,而不是在onBlur(在沙箱中:仅用于打印)中执行任何操作。

解决方法

FieldInput定义中,您在onBlur每次渲染时都调用该函数。

为防止这种情况发生,您可以使用箭头功能,React仅在模糊时渲染该箭头功能

onBlur={(fieldType) => handleBlur(fieldType)}

您可以在React.js文档中找到更详细的解释:

https://reactjs.org/docs/faq-functions.html

,

onBlur 是使用 Formik 的默认行为。无论您是否点击表单外的内容,它都会在您聚焦一个字段时触发。

并且 onBlur 将在任何 onClick 事件之前触发。

不过有几个解决方法。

  1. 使用 onMouseDown (& onKeyDown) 代替 onClick

基本上,onMouseDown 会在 onBlur 之前被调用。 在此处查看示例实现:https://github.com/formium/formik/issues/2062

<a
    href="#back-to-previous"
    onMouseDown={onClick}
    onKeyUp={(e) => {
      e.key === 'Enter' && onClick(e);
    }}
>

onKeyDown 是为了可访问性,您应该检查按下的是 Enter 键,而不是任意键。

  1. 覆盖 onBlur 并有条件地调用 formik onBlur

这可能听起来很老套,但它可能适合某些场景。

示例:

onBlur={(e) => {
  const wasLinkClicked = e.relatedTarget && e.relatedTarget.tagName === 'A';
   if (!wasLinkClicked) {
      handleBlur(e);
  }
}}

该代码检查您是否点击了链接。在你的例子中,你可以写一个不同的逻辑:“是表单内被点击的按钮吗?”。