停止 handleBlur 执行任何操作

11 浏览
0 Comments

停止 handleBlur 执行任何操作

在我的Formik表单中,当我点击搜索按钮时,会显示一个项目列表(UsersFoundList)。这个列表在表单之外,列表中的每个项目都有自己的按钮。

当我首次点击列表中的任何一个按钮时,它们不起作用。相反,会触发表单的handleBlur,并且由于输入字段为空,输入字段下方会显示错误消息。所以,按钮在第一次尝试时无法执行预期的操作。我通过在handleBlur中编写控制台日志来测试handleBlur。

这个错误应该只在我尝试再次提交表单时显示。而不是在我点击其他任何东西时显示。

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

const handleSubmitForm = (

values: FormValues,

helpers: FormikHelpers,

) => {

console.log('hello', values.input)

setShowFlatList(true);

helpers.resetForm();

};

return (

initialValues={initialValues}

onSubmit={handleSubmitForm}

validationSchema={addRelationValidationSchema}>

{({ handleChange, handleBlur, handleSubmit, values }) => (

handleChange={handleChange}

handleBlur={handleBlur}

value={values.input}

fieldType="input"

icon="user"

placeholderText="E-Mail oder Telefonnummer oder Name"

/>

name="input"

render={(msg) => }

/>

)}

{showFlatList && (

)}

);

如果在手机上运行codesandbox,您可以看到问题:

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

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

我点击的按钮有一个单独的函数,并且该按钮位于表单之外,所以它应该执行其原始预期操作,而不是在onBlur中执行任何操作(在sandbox中只是打印)。

0
0 Comments

在你的FieldInput定义中,你在每次渲染时都调用了onBlur函数。

为了阻止这种情况发生,你可以使用箭头函数,React只会在失焦时渲染它。

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

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

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

你是指fieldType吗?我已经尝试过onBlur={() => handleChange(fieldType)}但它不起作用。列表中的按钮在第一次点击后仍然不起作用。

你正在尝试传递参数,(fieldType) => handledChange(fieldType)

TypeScript期望第一个参数是事件,所以(event, fieldType) => handleBlur(_event, fieldType)可能是你需要的

即使这样,当我点击按钮/UserFoundENtry时,handleBlur仍然被调用。

当你点击按钮时,你希望onBlur被触发。这是onBlur事件的预期行为。你需要在函数中处理这个问题

不,我希望onBlur不会触发。我点击的按钮有一个单独的函数。而且这个按钮在表单外面,所以它应该按照它原来的预期功能工作,而不是在onBlur中做任何事情(在sandbox中只是打印)。你看过codesandbox了吗?也许它会给你一个更清晰的图片。

你有机会看一下吗?

我看了。但你已经改变了问题,解决了代码中的其他错误。我的最初答案是对你最初问题的回答。问题太过宽泛和不清楚。很抱歉,但我不认为我愿意完美地调试这段代码

"你在每次渲染时都调用了函数"是什么意思?写onBlur={handleBlur}onBlur={(e) => handleBlur(e)}完全相同,只是更简洁。

0
0 Comments

问题的原因是onBlur会在点击表单外的元素时触发,而且会在任何onClick事件之前触发。解决方法有两种。

第一种方法是使用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键,而不是任意键。

第二种方法是重写onBlur,并在条件满足时调用formik的onBlur。这种方法可能有些hacky,但在某些场景下可能适用。例如:

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

这段代码检查你是否点击了链接。在你的情况下,你可以编写不同的逻辑:"点击的按钮是否在表单内部"。

0