javascript - Validación de Formik para Input de Native Base
Estoy usando el campo de entrada de Native Base y estoy tratando de validarlo usando Formik y Yup. Sin embargo, hasta ahora no se está realizando ninguna validación. No muestra ningún error incluso si escribo letras.
Este código funciona (sin Formik):
type EmailRegistrationProps = {};
interface FormValues {
friendEmail: string;
}
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
rounded
style={scaledAddFriendEmailStyles.button}
onPress={() => handleSubmit()}
>
<Text style={scaledAddFriendEmailStyles.text}>
Add Friend{' '}
</Text>
</Button>
</View>
{/* </View>
)}
</Formik> */}
</View>
</View>
</View>
</SafeAreaView>
</Modal>
);
};
Ahora estoy intentando agregar Formik:
EDITAR:
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>
);
};
Actualmente, esto no está funcionando para mí. Quiero seguir usando mi antiguo handleSubmit que estoy usando a través del onPress del botón. Pero ahora no sé cómo pasar los valores, helpers a este handleSubmit:
onPress={() => handleSubmit()}
Recibo Se esperaban 2 argumentos, pero se obtuvieron 0.
Pero si intento pasar values, helpers estos nombres no se encuentran. De manera similar, estoy usando
[friendEmail, addFriend],
al final de getFriendId. Esto funcionaba correctamente si solo usaba setState sin la validación de Formik, etc. Pero ahora friendEmail no se puede encontrar. Simplemente no puedo integrar Formik correctamente de tal manera que también pueda restablecer valores como puedo hacer al usar useState.
Respuesta #1
Formik requiere que utilices el componente <Field /> para la validación.
<Field />conectará automáticamente los inputs a Formik. Utiliza el atributo name para coincidir con el estado de Formik.<Field />por defecto será un elemento HTML<input />.
Puedes establecer componentes personalizados mediante la propiedad component.
En tu caso, por ejemplo:
<Field
component={Input}
name="phoneNumber"
placeholder="Phone Number"
onChangeText={handleChange}
onBlur={handleBlur}
type='tel'
value={values.phoneNumber}
/>
Actualizar
Ahh, mi culpa, actualicé el onChangeText y el onBlur para reflejar los cambios. En la implementación actual, en realidad estás ejecutando los eventos "handle" al cargar en lugar de cuando ocurre el evento. Si le das un name al input, debería pasar esa información automáticamente. Además, deberías establecer un tipo para el input. He actualizado el ejemplo anterior con todas estas actualizaciones.
