Reputation:
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>
);
};
Why am I unable to write anything inside my Input field? I have tried using onChange
and handleChange
both but it doesn't make a difference. Other SO answers suggested that I should remove value
but examples of Formik usage that I see online suggest otherwise.
I am trying to follow this for my Formik validation:
EDIT:
I also tried with setFieldValue
but I still cannot type anything.
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>
);
};
Upvotes: 4
Views: 4712
Reputation: 354
Formik now works fine with React Native, but another thing to be aware of is that the name
in your form control must match the name of the property in the schema used by Formik.
For example, if using the following Yup schema:
const schema = yup.object({
personName: yup.string().required('Name required')
});
Then the following won't work because the Yup schema (personName
) and the form control (nameofPerson
) don't match; the user won't be able to type into the field:
<Form.Control
name="nameOfPerson"
value={values.personName}
onChange={handleChange}
onBlur={handleBlur}
type="text"
isValid={!errors.personName && !!touched.personName}
isInvalid={!!errors.personName && !!touched.personName}
/>
To make it work, the name
should be the same as the Yup property; in this case, personName
:
<Form.Control
name="personName"
value={values.personName}
onChange={handleChange}
onBlur={handleBlur}
type="text"
isValid={!errors.personName && !!touched.personName}
isInvalid={!!errors.personName && !!touched.personName}
/>
This example is using React-Bootstrap Form.Control
but should apply to any manner of creating form controls.
Upvotes: 0
Reputation: 3248
I think there are a couple of issues in your codebase.
onChangeText={handleChange('friendEmail')}
. It will trigger the handleChange
while rendering the component not when you are actualy typing in the input box.handleChange
function of Formik
takes React.ChangeEvent
instead of value. Check here . While onChangeText
of react-native
provides changed text of the input not event. Check hereYou can use setFieldValue
function for this case:
<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>
Please Note: I've never used formik
with react-native
. Just trying to connect the dots.
Upvotes: 0
Reputation: 301
try this:
<Input
placeholder="Email"
onChange={e => setFieldValue('friendEmail', e.currentTarget.value)}
onBlur={handleBlur}
value={values.friendEmail}
autoCapitalize="none"
/>
Upvotes: 0
Reputation: 281734
Formik's Field component doesn't support React native yet. Check this github issue for more details
However you can make use of TextInput in place of field and use it with onChangeText handler
<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>
you can read more about Formik's usage with react-native in its documentation here
Upvotes: 1