停止 handleBlur 执行任何操作
停止 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中只是打印)。
在你的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)}
完全相同,只是更简洁。
问题的原因是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); } }}
这段代码检查你是否点击了链接。在你的情况下,你可以编写不同的逻辑:"点击的按钮是否在表单内部"。