Formik Validation for Native Base Input

五迷三道 提交于 2021-02-09 03:00:42

问题


I am using native base's input field and am trying to validate it using Formik and Yup. However, no validation is happening so far. It doesn't show any errors even if I type alphabets.

This code works (without 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>
  );
};

Now I am trying to add Formik:

EDIT:

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. I want to keep using my old handleSubmit that I am using via the onPress of the button. But now I don't know how to pass the values, helpers into this handleSubmit:

onPress={() => handleSubmit()}

I get Expected 2 arguments, but got 0.

But if I try to pass values, helpers these names are not found. Similarly, I am using

[friendEmail, addFriend],

at the end of getFriendId. This was working properly if I just use setState without formik validation etc. But now friendEmailcan't be found. I am just unable to merge Formik properly in such a way that I can also reset values like I can do while using useState.


回答1:


Formik requires you to utilize the <Field /> component for validation.

<Field /> will automagically hook up inputs to Formik. It uses the name attribute to match up with Formik state. <Field /> will default to an HTML <input /> element.

You can set custom components via the component prop.

In your case, for example:

<Field
    component={Input}
    name="phoneNumber"
    placeholder="Phone Number"
    onChangeText={handleChange}
    onBlur={handleBlur}
    type='tel'
    value={values.phoneNumber}
/>

Update

Ahh, my bad, I updated the onChangeText and onBlur to reflect the changes. In the current implementation you're actually running the "handle" events on load rather than when the even occurs. If you name the input it should pass that information along automagically. Also, you should set a type for the input. I've updated the above example for all of these updates.



来源:https://stackoverflow.com/questions/61499741/formik-validation-for-native-base-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!