onChange on TextInput Not Working Inside Formik
Asked Answered
R

3

1

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.

Roadhouse answered 8/5, 2020 at 23:26 Comment(3)
Instead of passing onChangeText={setEmail} prop to TextInput pass onChange={handleChange}Defalcate
Already tried that. I still can't type anything into it @TridevMishraRoadhouse
Then maybe I am not correctly wrapping it all within Formik?Roadhouse
G
3

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.

Greenbelt answered 9/5, 2020 at 3:48 Comment(2)
The property name doesn't exist on TextInput or Input. It always gives No overload matches this call.Roadhouse
@a125 Strange. But formik understands fields with nameGreenbelt
F
0

I'm using Formik Hooks. Here is a code you can use and adapt to yours:

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>
  );
};
Frigid answered 26/4, 2022 at 1:23 Comment(0)
H
0

You can solve this issue by simply adding the touched object and handle blur method to the formik and validate your textinput on the these conditions will solve your issue here is the code snippet

<Formik
        initialValues={{
          email: '',
          password: '',
        }}
        validationSchema={formSchema}
        validateOnChange={true}
        validateOnBlur
        onSubmit={values =>
          handleCreate(values.email, values.password)
        }>
        {({
          values,
          handleChange,
          handleBlur,
          handleSubmit,
          touched,
          errors,
        }) => (
          <>
            <TextField
              label={'Email'}
              onChangeText={handleChange('email')}
              value={values.email}
              // onFocus={()=>setEmailFocused(true)}
              onBlur={handleBlur('email')}
            />
            {errors.email&&touched.email && (
              <View flexDir={'row'} alignItems={'center'} mt={1} ml={2}>
                <View
                  bg={'red.500'}
                  h={1}
                  w={1}
                  rounded={'full'}
                  mx={1}></View>
                <Text color={'red.500'} fontSize={12}>
                  {errors.email}
                </Text>
              </View>
            )}
            <TextField
              label={'Password'}
              onChangeText={handleChange('password')}
              value={values.password}
              onBlur={handleBlur('email')}
            />
            {errors.password &&touched.password&& (
              <View flexDir={'row'} alignItems={'center'} mt={1} ml={1}>
                <View
                  bg={'red.500'}
                  h={1}
                  w={1}
                  rounded={'full'}
                  mx={1}></View>
                <Text color={'red.500'} fontSize={12}>
                  {errors.password}
                </Text>
              </View>
            )}
            <TouchableOpacity
              onPress={() => {
                navigation.navigate('ForgetPassword');
              }}>
              <Text
                fontSize={'16'}
                mr={2}
                textAlign={'right'}
                color={'pro'}
                mt={4}
                fontFamily={'Jost-Medium'}>
                Forgot Password?
              </Text>
            </TouchableOpacity>

            <View mt={'40%'}>
              <AButtons label={'Sign In'} loading={isLoading} onPress={()=>{if(values?.email!==''||values?.password!==''){handleSubmit()}
            else{
              setEmailFocused(true);
              setPasswordFocused(true);
            }
            }} />
            </View>
          </>
        )}
      </Formik>
Haematopoiesis answered 22/1 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.