Búsqueda de sitios web

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.

Artículos relacionados