'onChange on TextInput Not Working Inside Formik

Generally <TextInput> allows you to type even when you're just specifying a placeholder. However, when using within the Formik form, I am unable to type and validate anything in my form. What am I doing wrong?

I have tried onChangeTextwith setFieldValueand handleChangeboth.

const initialValues: FormValues = {
  friendEmail: '',
};

export const Page: React.FunctionComponent<Props> = ({
  toggleShowPage,
  showPage,
}) => {

  const validationSchema = emailValidationSchema;

  const getFriendId = React.useCallback(
    (data: any) => {
      //console.log('Email', initialValues.friendEmail);
      if (data) {
        if (data.users.nodes.length == 0) {
         ...
        } else {
          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>
          <View>
            <View>
              <Formik
                initialValues={initialValues}
                onSubmit={handleSubmitForm}
                validationSchema={validationSchema}>
                {({
                  handleChange,
                  setFieldValue,
                  setFieldTouched,
                  handleBlur,
                  handleSubmit,
                  isSubmitting,
                  values,
                }) => {
                  const setEmail = (friendEmail: string) => {
                    setFieldValue('friendEmail', friendEmail)
                    setFieldTouched('friendEmail', true, false);
                  }
                return(
                  <Form>
                  <View>
                    <View>                  
                      <Item>
                      <TextInput
                      placeholder="Email"
                      onChangeText={setEmail}
                      //onChangeText={handleChange}
                      //onChangeText={handleChange('friendEmail')}
                      //onChangeText={e => console.log('Workinggg')}
                      //onBlur={handleBlur('friendEmail')}
                      //value={values.friendEmail}
                      autoCapitalize="none"
                      />                      
                      </Item>
                    </View>
                    <View>
                      <Button
                        onPress={handleSubmit}>
                        <Text>
                          Add{' '}
                        </Text>
                      </Button>
                    </View>
                  </View>
                  </Form>
                )}}
              </Formik>
            </View>
          </View>
        </View>
      </SafeAreaView>
    </Modal>
  );
};

How can I fix the textInput to make the typing and validation work?

According to this: https://jaredpalmer.com/formik/docs/guides/react-native

We don't need to use the name property. I have used this onChangeText too but I still can't write anything.



Solution 1:[1]

In your case if your TextInput returns value at first parameter like you use all right. But you mistake give name to field:

<TextInput
  name="friendEmail"
  placeholder="Email"
  onChangeText={setEmail}
  autoCapitalize="none"
/> 

Formik doesn't know where to set your value if you don't give name to field. And also you can do like:

<TextInput
  name="friendEmail"
  placeholder="Email"
  onChangeText={(val) => {
    setFieldValue('friendEmail', val)
    setFieldTouched('friendEmail', true, false);
  }
  autoCapitalize="none"
/> 

My advice is to modify or write wrapper for TextInput. And field should return onChange first parameter name, and second value. It will be more useful. And you can read more about your problem on official docs.

Solution 2:[2]

i'm using Formik Hooks, here is a code you can use it and adapt to yours, hope it will help you :)

import {useFormik} from 'formik';
import React from 'react';
import {StyleSheet, TextInput, View} from 'react-native';

const styles = StyleSheet.create({
  input: {
    height: 40,
    margin: 12,
    borderWidth: 1,
    padding: 10,
    borderRadius: 10,
  },
});

const TestFormik = () => {
  const formik = useFormik({
    initialValues: {
      email: '',
      password: '',
    },
    onSubmit: async (values, {setSubmitting}) => {
      console.log(values);
      setSubmitting(false);
    },
  });

  return (
    <View>
      <TextInput
        style={styles.input}
        onChangeText={formik.handleChange('email')}
        onBlur={formik.handleBlur('email')}
        value={formik.values.email}
        placeholder="Email"
      />
      <TextInput
        style={styles.input}
        onChangeText={formik.handleChange('password')}
        onBlur={formik.handleBlur('password')}
        value={formik.values.password}
        placeholder="Password"
      />
      <Button title="Submit" onPress={formik.handleSubmit} />
    </View>
  );
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 aturan23
Solution 2 Dako Junior