I had a native base's input field which reads a value that is then used in a graphql query and mutation. I wanted to add Formik Validation to it. I read that in order to use Formik validation, I would need to use Field
instead of Input
.
This is my code logic, which works without Formik validation so far. Here I am using useState
instead of Formik values. The handleSubmit
happens onPress
of the button:
type AddFriendEmailPageProps = { toggleShowPage: () => void; showAddFriendEmailPage: boolean;};export const AddFriendEmailPage: React.FunctionComponent<AddFriendEmailPageProps> = ({ toggleShowPage, showAddFriendEmailPage,}) => { const [friendEmail, setFriendEmail] = useState(''); const [errorMessage, setErrorMessage] = useState(''); const validationSchema = emailValidationSchema; const showAlert = () => { Alert.alert('Friend Added'); } useEffect(() => { if (showAddFriendEmailPage) return; setFriendEmail(''); }, [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', friendEmail); if (data) { if (data.users.nodes.length == 0) { setErrorMessage('User Not Found'); } else { addFriend(Number(data.users.nodes[0].id)); } } }, [friendEmail, addFriend], ); const [loadUsers] = useUsersLazyQuery({ onCompleted: getFriendId, onError: _onLoadUserError, }); const handleSubmit = React.useCallback(() => { loadUsers({ variables: { where: { email: friendEmail }, }, }); setFriendEmail(''); }, [loadUsers, friendEmail]); } 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}><Item style={scaledAddFriendEmailStyles.searchField}><Input placeholder="Email" style={scaledAddFriendEmailStyles.searchText} onChangeText={(text) => setFriendEmail(text)} value={friendEmail} autoCapitalize="none" /></Item><View style={scaledAddFriendEmailStyles.buttonContainer}><Button onPress={() => handleSubmit()}><Text style={scaledAddFriendEmailStyles.text}> Add Friend{''}</Text></Button></View></View></View></View></SafeAreaView></Modal> );};
Now I am trying to add Formik. But I want to somehow use the same handleSubmit. Otherwise, the hooks and logic might get messed up. This is what I was trying:
export const AddFriendEmailPage: React.FunctionComponent<AddFriendEmailPageProps> = ({ toggleShowPage, showAddFriendEmailPage,}) => { const initialValues: FormValues = { friendEmail: '', }; //const [friendEmail, setFriendEmail] = useState(''); const [errorMessage, setErrorMessage] = useState(''); const validationSchema = emailValidationSchema; const showAlert = () => { Alert.alert('Friend Added'); } 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', 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)); } } }, [friendEmail, addFriend], ); const [loadUsers] = useUsersLazyQuery({ onCompleted: getFriendId, onError: _onLoadUserError, }); const handleSubmit = React.useCallback(( values: FormValues, helpers: FormikHelpers<FormValues>, ) => { console.log('Submitted'); loadUsers({ variables: { where: { email: values.friendEmail }, }, }); //setFriendEmail(''); values.friendEmail = ''; }, [loadUsers, initialValues.friendEmail]); } 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 > Add Friend by Email</Text><Text> Done</Text></View><View style={scaledAddFriendEmailStyles.searchFieldContainer}><Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={validationSchema}> {({ handleChange, handleBlur, handleSubmit, isSubmitting, values, }) => ( <Field component={Input} placeholder="Email" onChangeText={handleChange('friendEmail')} onBlur={handleBlur('friendEmail')} value={values.friendEmail} autoCapitalize="none" /> )}</Formik><View ><Button onPress={() => handleSubmit()}><Text > Add Friend{''}</Text></Button></View></View></View></View></SafeAreaView></Modal> );};
Currently, this is not working for me. For example, now I don't know how to pass the values, helpers
into this handleSubmit
:
onPress={() => handleSubmit()}
error: Expected 2 arguments, but got 0.
Passing values, helpers
gives me these names are not found
of course.
Similarly, I was using
[friendEmail, addFriend],
at the end of getFriendId()
callback earlier. Now friendEmail
can't be found. I am just unable to merge Formik properly in such a way that I can also reset values after the form is submitted. like I can do while using useState
. I am unable to put it all together.