无法输入 <Formik> 字段
Posted
技术标签:
【中文标题】无法输入 <Formik> 字段【英文标题】:Unable to Type in <Formik> Field 【发布时间】:2020-08-22 19:09:45 【问题描述】:interface FormValues
friendEmail: string;
const initialValues: FormValues =
friendEmail: '',
;
export const Page: React.FunctionComponent<PageProps> = (
toggleShowPage,
showPage,
) =>
const [errorMessage, setErrorMessage] = useState('');
const validationSchema = emailValidationSchema;
useEffect(() =>
if (showPage) return;
initialValues.friendEmail = '';
, [showPage]);
const [
createUserRelationMutation,
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled,
,
] = useCreateUserRelationMutation(
onCompleted: (data: any) =>
showAlert();
,
);
const addFriend = React.useCallback(
(id: Number) =>
console.log('Whats the Id', id);
createUserRelationMutation(
variables:
input: relatedUserId: id, type: RelationType.Friend, userId: 7 ,
,
);
,
[createUserRelationMutation],
);
const getFriendId = React.useCallback(
(data: any) =>
//console.log('Email', initialValues.friendEmail);
if (data)
if (data.users.nodes.length == 0)
console.log('No user');
setErrorMessage('User Not Found');
Alert.alert('User Not Found');
else
console.log('ID', data.users.nodes[0].id);
addFriend(Number(data.users.nodes[0].id));
,
[addFriend],
//[friendEmail, addFriend],
);
const [loadUsers] = useUsersLazyQuery(
onCompleted: getFriendId,
onError: _onLoadUserError,
);
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) =>
console.log('Submitted');
loadUsers(
variables:
where: email: values.friendEmail ,
,
);
//setFriendEmail('');
values.friendEmail = '';
,
[loadUsers],
//[loadUsers, friendEmail]
);
if (!addingFriendLoading && isMutationCalled)
if (addingFriendData)
console.log('Checking');
if (addingFriendError)
console.log('errorFriend', addingFriendError.message);
return (
<Modal
visible=showAddFriendEmailPage
animationType="slide"
transparent=true>
<SafeAreaView>
<View style=scaledAddFriendEmailStyles.container>
<View style=scaledAddFriendEmailStyles.searchTopContainer>
<View style=scaledAddFriendEmailStyles.searchTopTextContainer>
<Text
style=scaledAddFriendEmailStyles.searchCancelDoneText
onPress=toggleShowPage>
Cancel
</Text>
<Text style=scaledAddFriendEmailStyles.searchTopMiddleText>
Add Friend by Email
</Text>
<Text style=scaledAddFriendEmailStyles.searchCancelDoneText>
Done
</Text>
</View>
<View style=scaledAddFriendEmailStyles.searchFieldContainer>
<Formik
initialValues=initialValues
onSubmit=handleSubmitForm
validationSchema=validationSchema>
(
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
) => (
<View>
<View>
<Item style=scaledAddFriendEmailStyles.searchField>
<TextInput
style=scaledAddFriendEmailStyles.searchText
placeholder="Email"
onChangeText=handleChange('friendEmail')
//onChangeText=e => console.log('Workinggg')
onBlur=handleBlur('friendEmail')
value=values.friendEmail
autoCapitalize="none"
/>
/* <Field
component=Input
name='friendEmail'
placeholder="Email"
//handleChange=handleChange
handleBlur=handleBlur
//onChange=handleChange
//onChangeText=handleChange('friendEmail')
//onBlur=handleBlur('friendEmail')
value=values.friendEmail
autoCapitalize="none"
/> */
</Item>
</View>
<View>
<Button
onPress=handleSubmit>
<Text>
Add Friend' '
</Text>
</Button>
</View>
</View>
)
</Formik>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
);
;
为什么我无法在输入字段中写入任何内容?我尝试过使用onChange
和handleChange
both,但这并没有什么不同。其他 SO 答案建议我应该删除 value
,但我在网上看到的 Formik 用法示例另有说明。
我正在尝试按照这个进行我的 Formik 验证:
https://heartbeat.fritz.ai/build-and-validate-forms-in-react-native-using-formik-and-yup-6489e2dff6a2
编辑:
我也尝试过setFieldValue
,但我仍然无法输入任何内容。
const initialValues: FormValues =
friendEmail: '',
;
export const AddFriendEmailPage: React.FunctionComponent<AddFriendEmailPageProps> = (
toggleShowPage,
showAddFriendEmailPage,
) =>
const [errorMessage, setErrorMessage] = useState('');
const validationSchema = emailValidationSchema;
useEffect(() =>
if (showAddFriendEmailPage) return;
initialValues.friendEmail = '';
, [showAddFriendEmailPage]);
const _onLoadUserError = React.useCallback((error: ApolloError) =>
setErrorMessage(error.message);
Alert.alert('Unable to Add Friend');
, []);
const [
createUserRelationMutation,
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled,
,
] = useCreateUserRelationMutation(
onCompleted: (data: any) =>
showAlert();
,
);
const addFriend = React.useCallback(
(id: Number) =>
console.log('Whats the Id', id);
createUserRelationMutation(
variables:
input: relatedUserId: id, type: RelationType.Friend, userId: 7 ,
,
);
,
[createUserRelationMutation],
);
const getFriendId = React.useCallback(
(data: any) =>
//console.log('Email', initialValues.friendEmail);
if (data)
if (data.users.nodes.length == 0)
console.log('No user');
else
console.log('ID', data.users.nodes[0].id);
addFriend(Number(data.users.nodes[0].id));
,
[addFriend],
//[friendEmail, addFriend],
);
const [loadUsers] = useUsersLazyQuery(
onCompleted: getFriendId,
onError: _onLoadUserError,
);
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) =>
console.log('Submitted');
loadUsers(
variables:
where: email: values.friendEmail ,
,
);
//setFriendEmail('');
values.friendEmail = '';
,
[loadUsers],
//[loadUsers, friendEmail]
);
return (
<Modal
visible=showPage
animationType="slide"
transparent=true>
<SafeAreaView>
<View style=scaledAddFriendEmailStyles.container>
<View style=scaledAddFriendEmailStyles.searchFieldContainer>
<Formik
initialValues=initialValues
onSubmit=handleSubmitForm
validationSchema=validationSchema>
(
handleChange,
setFieldValue,
handleBlur,
handleSubmit,
isSubmitting,
values,
) =>
const setEmail = (friendEmail: string) =>
setFieldValue('friendEmail', friendEmail)
return(
<View>
<View>
<Item>
<TextInput
placeholder="Email"
onChangeText=setEmail
onBlur=handleBlur('friendEmail')
value=values.friendEmail
autoCapitalize="none"
/>
</Item>
</View>
<View >
<Button
onPress=handleSubmit>
<Text >
Add Friend' '
</Text>
</Button>
</View>
</View>
)
</Formik>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
);
;
【问题讨论】:
onChange=handleChange
应该可以工作。不要使用handleChange=handleChange
已经尝试过了,但没有用@ShubhamKhatri
按功能划分 - 将 formik/form 逻辑移动到自己的组件中,在内部使用useFormik
...传递handleSubmitForm
[或loadUsers
] 作为道具
【参考方案1】:
Formik 的 Field 组件还不支持 React native。更多详情请查看this github issue
但是,您可以使用 TextInput 代替字段并将其与 onChangeText 处理程序一起使用
<Formik
initialValues=initialValues
onSubmit=handleSubmitForm
validationSchema=validationSchema>
(
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
) => (
<View>
<View>
<Item style=scaledAddFriendEmailStyles.searchField>
<TextInput
placeholder="Email"
onChangeText=handleChange('friendEmail')
onBlur=handleBlur('friendEmail')
value=values.friendEmail
/>
</Item>
</View>
<View >
<Button
onPress=handleSubmit
>
<Text >
Add Friend' '
</Text>
</Button>
</View>
</View>
)
</Formik>
您可以在其documentation here 中阅读更多有关 Formik 与 react-native 的用法
【讨论】:
我仍然无法在此 TextField 中输入任何内容。也许问题出在代码中的其他地方 有什么想法吗? 哦,天哪,这很难指出。尝试键入字符时是否有任何重新渲染。可能是因为您直接在功能组件中定义了初始值,并且每次键入字符时引用都会更改。尝试将其移出组件,看看您是否仍然遇到问题 将初始值移到外面也不起作用。我认为我没有在其他任何地方使用另一个显式渲染。我在上面添加了完整的代码【参考方案2】:试试这个:
<Input
placeholder="Email"
onChange=e => setFieldValue('friendEmail', e.currentTarget.value)
onBlur=handleBlur
value=values.friendEmail
autoCapitalize="none"
/>
【讨论】:
输入没有名称属性。即使我将其注释掉,我仍然无法输入任何内容。 如果您注释掉名称,则 handleChange 将不起作用。如果您要从字段中删除名称,只需尝试onChange=e => setFieldValue('friendEmail', e.currentTarget.value)
这给了我Property 'value' does not exist on type 'number'.
。这很奇怪,因为我没有在任何地方使用数字......
尝试给e
输入any
,如果有效,然后将any
更改为事件的类型。 onChange=(e: any) => setFieldValue('friendEmail', e.currentTarget.value)
【参考方案3】:
我认为您的代码库中有几个问题。
onChangeText=handleChange('friendEmail')
。它会在渲染组件时触发handleChange
,而不是在您实际在输入框中输入时。
Formik
的 handleChange
函数采用 React.ChangeEvent
而不是值。检查here。而onChangeText
的react-native
提供输入的更改文本而不是事件。检查here
您可以在这种情况下使用setFieldValue
函数:
<Formik
initialValues=initialValues
onSubmit=handleSubmitForm
validationSchema=validationSchema>
(
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
setFieldValue
) =>
const setEmail = (email) =>
setFieldValue('friendEmail', email)
return (
<View>
<View>
<Item style=scaledAddFriendEmailStyles.searchField>
<TextInput
placeholder="Email"
onChangeText=setEmail
value=values.friendEmail
/>
</Item>
</View>
</View>
)
</Formik>
请注意:我从未将formik
与react-native
一起使用。只是想把这些点联系起来。
【讨论】:
它对我还不起作用。也许问题出在其他地方。我编辑了 qs 以添加我的完整代码。另外,这样就没有用handleChange
into Formik right【参考方案4】:
Formik 现在可以很好地与 React Native 配合使用,但需要注意的另一件事是表单控件中的 name
必须与 Formik 使用的架构中的属性名称匹配。
例如,如果使用以下 Yup 架构:
const schema = yup.object(
personName: yup.string().required('Name required')
);
那么以下内容将不起作用,因为 Yup 架构 (personName
) 和表单控件 (nameofPerson
) 不匹配;用户将无法在该字段中输入:
<Form.Control
name="nameOfPerson"
value=values.personName
onChange=handleChange
onBlur=handleBlur
type="text"
isValid=!errors.personName && !!touched.personName
isInvalid=!!errors.personName && !!touched.personName
/>
要使其工作,name
应该与 Yup 属性相同;在这种情况下,personName
:
<Form.Control
name="personName"
value=values.personName
onChange=handleChange
onBlur=handleBlur
type="text"
isValid=!errors.personName && !!touched.personName
isInvalid=!!errors.personName && !!touched.personName
/>
此示例使用 React-Bootstrap Form.Control
,但应适用于任何创建表单控件的方式。
【讨论】:
以上是关于无法输入 <Formik> 字段的主要内容,如果未能解决你的问题,请参考以下文章
无法覆盖 formik Select 的 `onChange` 处理程序