touched 属性 未重置
touched property not being reset
我有一个 Formik 表单,我在其中接受用户输入并在提交后 运行 查询。
当我点击搜索按钮时,会呈现一个列表。所有列表项都有自己的按钮。当我第一次单击绿色添加按钮(来自列表项)时,该按钮不起作用。不打印控制台日志的内容。相反,会触发 inputField 的 onBlur 事件。但是,如果我再次单击 + 按钮,它就会工作并打印 no。此问题在 simulators/phones 中可见,而不是在沙盒的 Web 模式中。
export const AddFriendScreen: React.FunctionComponent = () => {
const initialValues: FormValues = {
input: '',
};
const [showFlatList, setShowFlatList] = useState<UsersLazyQueryHookResult>(
'',
);
const handleSubmitForm = (
values: FormValues,
helpers: FormikHelpers<FormValues>,
) => {
loadUsers({
variables: {
where: {
OR: [
{ phoneNumber: newPhoneNumber },],
},
},
});
helpers.resetForm();
};
return (
<SafeAreaView style={styles.safeAreaViewContainer}>
<View style={styles.searchTopContainer}>
<View style={styles.formContainer}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ 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}>
<ActionButton buttonText="Suchen" onPress={handleSubmit} />
</View>
</View>
)}
</Formik>
</View>
<View style={styles.listHolder}>
{data && showFlatList !== null && (
<UsersFoundList
data={data}/>
)}
</View>
</View>
</SafeAreaView>
);
};
小吃博览会:
https://snack.expo.io/@nhammad/jealous-beef-jerky
[![在此处输入图片描述][1]][1]
编辑:
找到了解决方法,但仍对更简单的解决方案持开放态度。仍然没有弄清楚到底是什么导致了这个问题。
However, this causes the formik error to show up immediately after the form is submitted and data is returned/rendered. For instance, the error suggests that the input field should not be empty.
...
Why is the keyboard interfering in this?
可能是因为当你调用Keyboard.dismiss()
时你实际上是在散焦输入,这将触发validateOnBlur
事件。
因此,当您取消聚焦某个字段(模糊)时,它会尝试验证 (validateOnBlur
),并且由于该字段为空,它会显示验证。
The error should only show up when we are trying to resubmit the form without an input.
如果错误应该只在您提交表单时显示,您应该传递给 Formik
组件 validateOnBlur={false}
。有了这个,当您调用 Keyboard.dismiss()
时它不会显示错误消息,因为它会删除对模糊的验证。
但是当输入改变时它仍然有效,触发validateOnChange
。您还可以传递给 Formik
组件 validateOnChange={false}
以禁用更改验证,它只会在您提交表单(按下按钮)时验证。
请注意validateOnChange
和validateOnBlur
默认为true
。
编辑:
您需要添加 validateOnBlur={false}
,但您需要调用 fieldRef.current.blur()
而不是调用 Keyboard.dismiss()
。但要使其工作,您需要在输入组件中使用 React.forwardRef
。
所以你需要创建 fieldRef
const fieldRef = useRef();
传递给组件
<FieldInput
ref={fieldRef} // passing the ref
handleChange={handleChange}
handleBlur={handleBlur}
value={values.input}
fieldType="input"
icon="user"
placeholderText="input"
/>
你需要用 React.forwardRef
环绕你的 FieldInput
并将 ref
传递给 Input
组件。
// wrapping the component with React.forwardRef
export const FieldInput: React.FunctionComponent<FieldInputProps> = React.forwardRef(({
handleChange,
handleBlur,
fieldType,
placeholderText,
value,
style,
rounded,
//ref,
}, ref) => {
return (
<Item rounded={rounded} style={[styles.inputItem, style]}>
<Input
ref={ref} // passing the ref
autoFocus={true}
autoCapitalize="none"
style={styles.inputField}
placeholder={placeholderText}
keyboardType="default"
onChangeText={handleChange(fieldType)}
onBlur={handleChange(fieldType)}
value={value}
/>
</Item>
);
});
而现在在 handleSubmitForm
你调用 fieldRef.current.blur()
const handleSubmitForm = (
values: FormValues,
helpers: FormikHelpers<FormValues>,
) => {
// other logic from your submit
if (fieldRef && fieldRef.current)
fieldRef.current.blur();
};
有了这个,你将解决你的问题和评论中的问题。
关于useRef
的说明
我们需要使用 useRef
钩子,以便我们可以获取 Input
组件的元素,以便能够调用 blur
函数,所以不要专注于输入并可以单击加号按钮。
我们需要使用 useRef
挂钩,因为这是在功能组件中创建 ref
的方式。
我有一个 Formik 表单,我在其中接受用户输入并在提交后 运行 查询。
当我点击搜索按钮时,会呈现一个列表。所有列表项都有自己的按钮。当我第一次单击绿色添加按钮(来自列表项)时,该按钮不起作用。不打印控制台日志的内容。相反,会触发 inputField 的 onBlur 事件。但是,如果我再次单击 + 按钮,它就会工作并打印 no。此问题在 simulators/phones 中可见,而不是在沙盒的 Web 模式中。
export const AddFriendScreen: React.FunctionComponent = () => {
const initialValues: FormValues = {
input: '',
};
const [showFlatList, setShowFlatList] = useState<UsersLazyQueryHookResult>(
'',
);
const handleSubmitForm = (
values: FormValues,
helpers: FormikHelpers<FormValues>,
) => {
loadUsers({
variables: {
where: {
OR: [
{ phoneNumber: newPhoneNumber },],
},
},
});
helpers.resetForm();
};
return (
<SafeAreaView style={styles.safeAreaViewContainer}>
<View style={styles.searchTopContainer}>
<View style={styles.formContainer}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ 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}>
<ActionButton buttonText="Suchen" onPress={handleSubmit} />
</View>
</View>
)}
</Formik>
</View>
<View style={styles.listHolder}>
{data && showFlatList !== null && (
<UsersFoundList
data={data}/>
)}
</View>
</View>
</SafeAreaView>
);
};
小吃博览会:
https://snack.expo.io/@nhammad/jealous-beef-jerky
[![在此处输入图片描述][1]][1]
编辑:
找到了解决方法,但仍对更简单的解决方案持开放态度。仍然没有弄清楚到底是什么导致了这个问题。
However, this causes the formik error to show up immediately after the form is submitted and data is returned/rendered. For instance, the error suggests that the input field should not be empty.
...
Why is the keyboard interfering in this?
可能是因为当你调用Keyboard.dismiss()
时你实际上是在散焦输入,这将触发validateOnBlur
事件。
因此,当您取消聚焦某个字段(模糊)时,它会尝试验证 (validateOnBlur
),并且由于该字段为空,它会显示验证。
The error should only show up when we are trying to resubmit the form without an input.
如果错误应该只在您提交表单时显示,您应该传递给 Formik
组件 validateOnBlur={false}
。有了这个,当您调用 Keyboard.dismiss()
时它不会显示错误消息,因为它会删除对模糊的验证。
但是当输入改变时它仍然有效,触发validateOnChange
。您还可以传递给 Formik
组件 validateOnChange={false}
以禁用更改验证,它只会在您提交表单(按下按钮)时验证。
请注意validateOnChange
和validateOnBlur
默认为true
。
编辑:
您需要添加 validateOnBlur={false}
,但您需要调用 fieldRef.current.blur()
而不是调用 Keyboard.dismiss()
。但要使其工作,您需要在输入组件中使用 React.forwardRef
。
所以你需要创建 fieldRef
const fieldRef = useRef();
传递给组件
<FieldInput
ref={fieldRef} // passing the ref
handleChange={handleChange}
handleBlur={handleBlur}
value={values.input}
fieldType="input"
icon="user"
placeholderText="input"
/>
你需要用 React.forwardRef
环绕你的 FieldInput
并将 ref
传递给 Input
组件。
// wrapping the component with React.forwardRef
export const FieldInput: React.FunctionComponent<FieldInputProps> = React.forwardRef(({
handleChange,
handleBlur,
fieldType,
placeholderText,
value,
style,
rounded,
//ref,
}, ref) => {
return (
<Item rounded={rounded} style={[styles.inputItem, style]}>
<Input
ref={ref} // passing the ref
autoFocus={true}
autoCapitalize="none"
style={styles.inputField}
placeholder={placeholderText}
keyboardType="default"
onChangeText={handleChange(fieldType)}
onBlur={handleChange(fieldType)}
value={value}
/>
</Item>
);
});
而现在在 handleSubmitForm
你调用 fieldRef.current.blur()
const handleSubmitForm = (
values: FormValues,
helpers: FormikHelpers<FormValues>,
) => {
// other logic from your submit
if (fieldRef && fieldRef.current)
fieldRef.current.blur();
};
有了这个,你将解决你的问题和评论中的问题。
关于useRef
的说明
我们需要使用 useRef
钩子,以便我们可以获取 Input
组件的元素,以便能够调用 blur
函数,所以不要专注于输入并可以单击加号按钮。
我们需要使用 useRef
挂钩,因为这是在功能组件中创建 ref
的方式。