'React Native Error: Element type is invalid (Formik)

I have a problem with Login Screen I am using Formik to use custom TextInputs but I am getting this error: (Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.)

This is my LoginScreen.js

import React, {useState} from 'react';
import { Alert,
         Image,
         KeyboardAvoidingView,
         ScrollView,
         StyleSheet,
         TouchableOpacity,
         View,
        } from 'react-native';
import AppText from '../../components/AppText';
import AppButton from '../../components/AppButton';
import colors from '../../configs/colors';
import AppInput from '../../components/AppInput';
import {Formik} from 'formik';
import * as Yup from 'yup';
import http from '../../services/http';
import storage from '../../services/storage';
import {setUser} from '../../store/reducers/auth';
import {CommonActions} from '@react-navigation/native';
import {useDispatch} from 'react-redux';
import ProgressDialog from 'react-native-progress-dialog';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';

const LoginScreen = ({navigation}) => {
 const dispatch = useDispatch();
 const [loading, setLoading] = useState(false);
 const loginUser = async values => {
   try {
     setLoading(true);
     values['role'] = 2;
     values['device_token'] ='XYZ';

     const res = await http.post({
    url: '/user/login',
    body: values,
  });
  console.log('Res => ', res.data);
  if (res.data.records.isVerified === 1) {
    dispatch(setUser(res.data));
    http.setUserTokenAndId(
      res.data.records.accessToken,
      res.data.records.id,
    );
    await storage.store('USER', res.data);
    navigation.dispatch(
      CommonActions.reset({
        index: 0,
        routes: [{name: 'Home'}],
      }),
    );
  } else {
    Alert.alert('Error', res.data.message, [
      {
        text: 'Resend Email',
        onPress: () => {
          resendEmail(res.data.records.accessToken);
        },
        style: 'destructive',
      },
      {
        text: 'Cancel',
        onPress: () => {},
        style: 'cancel',
      },
    ]);
  }
  } catch (err) {
  console.log('Err => ', err);
  } finally {
  setLoading(false);
  }
 };
 const resendEmail = async token => {
  try {
    setLoading(true);
    const res = await http.post({
       url: '/email/verification-notification',
       body: {},
       headers: {Authorization: 'Bearer ' + token},
     });
    Alert.alert('Success', res.data.message);
    } catch (err) {
     console.log('Err', err);
    } finally {
     setLoading(false);
    }
   };

  return (
  <View style={styles.container}>
    <View style={styles.cardContainer}>
      <View style={styles.card}>
        <View>
          <KeyboardAwareScrollView style={{height: '100%'}}>
            <>
            <Image source={require('../../assets/header.png')} />
            <AppText style={styles.headingText}>Sign In To Forsa</AppText>
            <AppText style={styles.subHeadingText}>
              Welcome Back! sign in to your previous account to continue the
              shoping
            </AppText>
          </>
          <View>
            <Formik
              initialValues={{email: '', password: ''}}
              validationSchema={Yup.object({
                email: Yup.string().label('Email').required(),
                password: Yup.string().label('Password').min(5).required(),
              })}
              onSubmit={loginUser}>
              {({submitForm}) => {
                return (
                  <View>
                    <Image
                      style={{
                        alignItems: 'center',
                        marginTop: 10,
                        height: 150,
                        width: '100%',
                      }}
                      resizeMode="contain"
                      source={require('../../assets/loginicon.png')}
                    />
                    <View style={{marginHorizontal: 20}}>
                      <AppInput
                        label=""
                        placeholder="Email*"
                        keyboardType="email-address"
                        name="email"
                        iconName="email"
                        autoComplete={true}
                        inputStyle={styles.input}
                        inputWrapperStyle={styles.inputWrapper}
                      />
                      <AppInput
                        label=""
                        placeholder="Password*"
                        name="password"
                        secureTextEntry={true}
                        iconName="lock"
                        inputWrapperStyle={styles.inputWrapper}
                        inputStyle={styles.input}
                      />
                    </View>
                    <AppButton
                      containerStyle={styles.loginBtn}
                      onPress={submitForm}
                      title={'Login'}></AppButton>
                    <View
                      style={{
                        justifyContent: 'space-between',
                        flexDirection: 'row',
                        marginTop: 10,
                      }}>
                      <View />
                      <AppText
                        style={{
                          color: colors.TAB_BAR_GREY,
                          fontSize: 13,
                          marginRight: 25,
                        }}
                        onPress={() =>
                          navigation.navigate('forgotPassword')
                        }>
                        Forgot Password?
                      </AppText>
                    </View>
                    <View
                      style={{
                        justifyContent: 'center',
                        flexDirection: 'row',
                        marginTop: 10,
                      }}>
                      <AppText>Don't have any account yet?</AppText>
                      <TouchableOpacity
                        onPress={() =>
                          navigation.navigate('CreateAccount')
                        }>
                        <AppText
                          style={{
                            marginLeft: 10,
                            color: colors.PRIMARY_GREEN,
                          }}>
                          Sign Up
                        </AppText>
                      </TouchableOpacity>
                    </View>
                  </View>
                );
              }}
            </Formik>
          </View>
        </KeyboardAwareScrollView>
      </View>

      {loading && (
        <ProgressDialog
          loaderColor={colors.PRIMARY_GREEN}
          visible={loading}
          labelStyle={{marginTop: 10}}
        />
      )}
    </View>
  </View>
</View>
);
};

export default LoginScreen;

const styles = StyleSheet.create({
  headingText: {
  fontSize: 30,
  position: 'absolute',
  marginTop: 80,
  marginLeft: 20,
  color: colors.WHITE,
  fontWeight: '600',
   },
  subHeadingText: {
  fontSize: 18,
  position: 'absolute',
  marginTop: 120,
  marginLeft: 20,
  color: colors.WHITE,
  fontWeight: '400',
   },
  loginBtn: {
  marginTop: 20,
  borderRadius: 50,
  marginHorizontal: 20,
   },
  input: {
  paddingLeft: 10,
  },
  inputWrapper: {
  borderWidth: 0.5,
  borderRadius: 50,
   },
  label: {
  color: colors.PRIMARY_GREEN,
   },
  loading: {
  position: 'absolute',
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  alignItems: 'center',
  justifyContent: 'center',
  // backgroundColor: "rgba(66,66,66,0.47)",
   },
  btnText: {
  color: colors.WHITE,
  fontSize: 16,
   },
  });

This is my AppInput.js (Which is custom TextInput):

import React from 'react';
import {View, TextInput, StyleSheet, Platform} from 'react-native';
import AppText from './AppText';
import {useFormikContext} from 'formik';
import colors from '../configs/colors';
import {MaterialCommunityIcons} from 'react-native-vector- 
                                      icons/MaterialCommunityIcons';

export default props => {
  const {
    name,
    label,
    labelStyle,
    inputWrapperStyle,
    inputWrapperErrorStyle,
    inputStyle,
    errorStyle,
    containerStyle,
    iconName,
    value,
    multiline = false,
    editable = true,
  } = props;
 const {values, errors, touched, setFieldValue} = useFormikContext();
 let wrapperErrorStyle = error
 ? {
    borderWidth: 1,
    borderColor: colors.ERROR_TEXT,
    ...inputWrapperErrorStyle,
  }
: {
    // borderWidth: 1,
    // borderColor: props.value ? colors.LIGHT_GREY : colors.LIGHT_GREY,
    ...inputWrapperErrorStyle,
  };
 const error = touched[name] && errors[name];

 let iconColor = props.value ? colors.PRIMARY_GREEN : colors.TAB_BAR_GREY;
 if (error) iconColor = colors.errorText;
  return (
    <View style={[styles.containerStyle, containerStyle]}>
     <AppText style={[styles.label, labelStyle]}>{label}</AppText>
      <View style={[styles.inputWrapper, inputWrapperStyle, wrapperErrorStyle]}>
       {iconName && (
        <MaterialCommunityIcons
          name={iconName}
          size={25}
          style={styles.iconStyles}
          color={iconColor}
      />
    )}
    <TextInput
      {...props}
      value={value}
      editable={editable}
      onChangeText={txt => {
        setFieldValue(name, txt);
      }}
      multiline={multiline}
      placeholderTextColor={colors.TAB_BAR_GREY}
      style={[styles.input, inputStyle]}
    />
  </View>
  {error ? (
    <AppText style={[styles.error, errorStyle]}>{error}</AppText>
  ) : null}
 </View>
 );
 };
 const styles = StyleSheet.create({
 containerStyle: {
   marginTop: Platform.OS === 'ios' ? 5 : 0,
   marginBottom: 0,
 },
 label: {
   fontSize: 15,
 },
 inputWrapper: {
   flexDirection: 'row',
   borderWidth: 0,
 },
 iconStyles: {
   justifyContent: 'center',
   alignItems: 'center',
   marginTop: 7,
   marginLeft: 18,
 },
 input: {
   flex: 1,
   minHeight: 40,
   maxHeight: 150,
   fontSize: 16,
   color: colors.BLACK,
 },
 error: {
   color: colors.ERROR_TEXT,
   marginTop: 3,
   fontSize: 16,
 },
});

I am searching from 3-4 hours but couldn't find any solution to this, I am kinda new to react native. Any help will be appreciated. Thank you.



Sources

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

Source: Stack Overflow

Solution Source