I have the following js:
import React, { useState, useEffect, useRef } from 'react';
import {
Text,
View,
TextInput,
Alert,
Image,
TouchableOpacity,
} from 'react-native';
import 'react-native-get-random-values';
import Button from 'react-native-button';
import PhoneInput from 'react-native-phone-input';
import { FirebaseRecaptchaVerifierModal } from 'expo-firebase-recaptcha';
import CodeField from 'react-native-confirmation-code-field';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { useColorScheme } from 'react-native-appearance';
import TNActivityIndicator from '../../truly-native/TNActivityIndicator';
import TNProfilePictureSelector from '../../truly-native/TNProfilePictureSelector/TNProfilePictureSelector';
import CountriesModalPicker from '../../truly-native/CountriesModalPicker/CountriesModalPicker';
import { IMLocalized } from '../../localization/IMLocalization';
import { setUserData } from '../redux/auth';
import { connect } from 'react-redux';
import authManager from '../utils/authManager';
import { localizedErrorMessage } from '../utils/ErrorCode';
import TermsOfUseView from '../components/TermsOfUseView';
import { firebase } from '../../firebase/config';
import dynamicStyles from './styles';
const SmsAuthenticationScreen = (props) => {
const appConfig =
props.navigation.state.params.appConfig ||
props.navigation.getParam('appConfig');
const appStyles =
props.navigation.state.params.appStyles ||
props.navigation.getParam('appStyles');
const colorScheme = useColorScheme();
const styles = dynamicStyles(appStyles, colorScheme);
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [loading, setLoading] = useState(false);
const [isPhoneVisible, setIsPhoneVisible] = useState(true);
const [phoneNumber, setPhoneNumber] = useState(false);
const [countriesPickerData, setCountriesPickerData] = useState(null);
const [verificationId, setVerificationId] = useState(null);
const [profilePictureURL, setProfilePictureURL] = useState(null);
const [countryModalVisible, setCountryModalVisible] = useState(false);
const myCodeInput = useRef(null);
const phoneRef = useRef(null);
const recaptchaVerifier = React.useRef(null);
const firebaseConfig = firebase.app().options;
const { isSigningUp } = props.navigation.state.params;
useEffect(() => {
if (phoneRef && phoneRef.current) {
setCountriesPickerData(phoneRef.current.getPickerData());
}
}, [phoneRef]);
const onFBButtonPress = () => {
authManager
.loginOrSignUpWithFacebook(appConfig.appIdentifier)
.then((response) => {
if (response.user) {
const user = response.user;
props.setUserData({ user });
props.navigation.navigate('MainStack', { user: user });
} else {
Alert.alert(
'',
localizedErrorMessage(response.error),
[{ text: IMLocalized('OK') }],
{
cancelable: false,
},
);
}
});
};
const signInWithPhoneNumber = (userValidPhoneNumber) => {
setLoading(true);
authManager.onVerification(userValidPhoneNumber);
authManager
.sendSMSToPhoneNumber(userValidPhoneNumber, recaptchaVerifier.current)
.then((response) => {
const confirmationResult = response.confirmationResult;
if (confirmationResult) {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
window.confirmationResult = confirmationResult;
setVerificationId(confirmationResult.verificationId);
setIsPhoneVisible(false);
setLoading(false);
} else {
// Error; SMS not sent
setLoading(false);
Alert.alert(
'',
localizedErrorMessage(response.error),
[{ text: IMLocalized('OK') }],
{ cancelable: false },
);
}
});
};
const signUpWithPhoneNumber = (smsCode) => {
const userDetails = {
firstName,
lastName,
phone: phoneNumber,
photoURI: profilePictureURL,
};
setLoading(true);
authManager
.registerWithPhoneNumber(
userDetails,
smsCode,
verificationId,
appConfig.appIdentifier,
)
.then((response) => {
if (response.error) {
Alert.alert(
'',
localizedErrorMessage(response.error),
[{ text: IMLocalized('OK') }],
{ cancelable: false },
);
} else {
const user = response.user;
props.setUserData({ user });
props.navigation.navigate('MainStack', { user: user });
}
setLoading(false);
});
};
const onPressSend = () => {
if (phoneRef.current.isValidNumber()) {
const userValidPhoneNumber = phoneRef.current.getValue();
setLoading(true);
setPhoneNumber(userValidPhoneNumber);
if (!isSigningUp) {
// If this is a login attempt, we first need to check that the user associated to this phone number exists
authManager
.retrieveUserByPhone(userValidPhoneNumber)
.then((response) => {
if (response.success) {
signInWithPhoneNumber(userValidPhoneNumber);
} else {
setPhoneNumber(null);
setLoading(false);
Alert.alert(
'',
IMLocalized(
'You cannot log in. There is no account with this phone number.',
),
[{ text: IMLocalized('OK') }],
{
cancelable: false,
},
);
}
});
} else {
signInWithPhoneNumber(userValidPhoneNumber);
}
} else {
Alert.alert(
'',
IMLocalized('Please enter a valid phone number.'),
[{ text: IMLocalized('OK') }],
{
cancelable: false,
},
);
}
};
const onPressFlag = () => {
setCountryModalVisible(true);
};
const onPressCancelContryModalPicker = () => {
setCountryModalVisible(false);
};
const onFinishCheckingCode = (newCode) => {
setLoading(true);
if (isSigningUp) {
signUpWithPhoneNumber(newCode);
} else {
authManager.loginWithSMSCode(newCode, verificationId).then((response) => {
if (response.error) {
Alert.alert(
'',
localizedErrorMessage(response.error),
[{ text: IMLocalized('OK') }],
{ cancelable: false },
);
} else {
const user = response.user;
props.setUserData({ user });
props.navigation.navigate('MainStack', { user: user });
}
setLoading(false);
});
}
};
const phoneInputRender = () => {
return (
<>
<PhoneInput
style={styles.InputContainer}
flagStyle={styles.flagStyle}
textStyle={styles.phoneInputTextStyle}
ref={phoneRef}
onPressFlag={onPressFlag}
offset={10}
allowZeroAfterCountryCode
textProps={{
placeholder: IMLocalized('Phone number'),
placeholderTextColor: '#aaaaaa',
}}
/>
{countriesPickerData && (
<CountriesModalPicker
data={countriesPickerData}
appStyles={appStyles}
onChange={(country) => {
selectCountry(country);
}}
cancelText={IMLocalized('Cancel')}
visible={countryModalVisible}
onCancel={onPressCancelContryModalPicker}
/>
)}
<Button
containerStyle={styles.sendContainer}
style={styles.sendText}
onPress={() => onPressSend()}>
{IMLocalized('Send code')}
</Button>
</>
);
};
const codeInputRender = () => {
return (
<>
<CodeField
ref={myCodeInput}
inputPosition="full-width"
variant="border-b"
codeLength={6}
size={50}
space={8}
keyboardType="numeric"
cellProps={{ style: styles.input }}
containerProps={{ style: styles.codeFieldContainer }}
onFulfill={onFinishCheckingCode}
/>
</>
);
};
const selectCountry = (country) => {
phoneRef.current.selectCountry(country.iso2);
};
const renderAsSignUpState = () => {
return (
<>
<Text style={styles.title}>{IMLocalized('Create new account')}</Text>
<TNProfilePictureSelector
setProfilePictureURL={setProfilePictureURL}
appStyles={appStyles}
/>
<TextInput
style={styles.InputContainer}
placeholder={IMLocalized('First Name')}
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setFirstName(text)}
value={firstName}
underlineColorAndroid="transparent"
/>
<TextInput
style={styles.InputContainer}
placeholder={IMLocalized('Last Name')}
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setLastName(text)}
value={lastName}
underlineColorAndroid="transparent"
/>
{isPhoneVisible ? phoneInputRender() : codeInputRender()}
<Text style={styles.orTextStyle}> {IMLocalized('OR')}</Text>
<Button
containerStyle={styles.signWithEmailContainer}
onPress={() =>
props.navigation.navigate('Signup', { appStyles, appConfig })
}>
{IMLocalized('Sign up with E-mail')}
</Button>
</>
);
};
const renderAsLoginState = () => {
return (
<>
<Text style={styles.title}>{IMLocalized('Sign In')}</Text>
{isPhoneVisible ? phoneInputRender() : codeInputRender()}
<Text style={styles.orTextStyle}> {IMLocalized('OR')}</Text>
<Button
containerStyle={styles.facebookContainer}
style={styles.facebookText}
onPress={() => onFBButtonPress()}>
{IMLocalized('Login With Facebook')}
</Button>
<Button
containerStyle={styles.signWithEmailContainer}
onPress={() =>
props.navigation.navigate('Login', { appStyles, appConfig })
}>
{IMLocalized('Sign in with E-mail')}
</Button>
</>
);
};
return (
<View style={styles.container}>
<KeyboardAwareScrollView
style={{ flex: 1, width: '100%' }}
keyboardShouldPersistTaps="always">
<TouchableOpacity onPress={() => props.navigation.goBack()}>
<Image
style={appStyles.styleSet.backArrowStyle}
source={appStyles.iconSet.backArrow}
/>
</TouchableOpacity>
{isSigningUp ? renderAsSignUpState() : renderAsLoginState()}
{isSigningUp && (
<TermsOfUseView tosLink={appConfig.tosLink} style={styles.tos} />
)}
<FirebaseRecaptchaVerifierModal
ref={recaptchaVerifier}
firebaseConfig={firebaseConfig}
/>
</KeyboardAwareScrollView>
{loading && <TNActivityIndicator appStyles={appStyles} />}
</View>
);
};
export default connect(null, {
setUserData,
})(SmsAuthenticationScreen);
I receive the following error and stack after I upgraded to the latest version of React Native:
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.
Check the render method of SmsAuthenticationScreen
.
This error is located at:
in RCTView (at View.js:34)
in View (at ScrollView.js:1124)
in RCTScrollView (at ScrollView.js:1260)
in ScrollView (at ScrollView.js:1286)
in ScrollView (at KeyboardAwareHOC.js:517)
in KeyboardAwareScrollView (at SmsAuthenticationScreen.js:340)
in RCTView (at View.js:34)
in View (at SmsAuthenticationScreen.js:339)
in SmsAuthenticationScreen (created by ConnectFunction)
in ConnectFunction (created by SceneView)
in SceneView (created by CardContainer)
in RCTView (at View.js:34)
in View (created by CardContainer)
in RCTView (at View.js:34)
in View (created by CardContainer)
in RCTView (at View.js:34)
in View (created by ForwardRef(CardSheet))
in ForwardRef(CardSheet) (created by Card)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (created by PanGestureHandler)
in PanGestureHandler (created by PanGestureHandler)
in PanGestureHandler (created by Card)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (created by Card)
in RCTView (at View.js:34)
in View (created by Card)
in Card (created by CardContainer)
in CardContainer (created by Context.Consumer)
in RNSScreen (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at src/index.native.js:111)
in Screen (created by MaybeScreen)
in MaybeScreen (created by Context.Consumer)
in RNSScreenContainer (at src/index.native.js:136)
in ScreenContainer (created by MaybeScreenContainer)
in MaybeScreenContainer (created by Context.Consumer)
in CardStack (created by KeyboardManager)
in KeyboardManager (created by Context.Consumer)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:74)
in SafeAreaProvider (created by Context.Consumer)
in SafeAreaProviderCompat (created by StackView)
in GestureHandlerRootView (at GestureHandlerRootView.android.js:31)
in GestureHandlerRootView (created by StackView)
in StackView (created by StackView)
in StackView
in Unknown (created by Navigator)
in Navigator (created by SceneView)
in SceneView (created by SwitchView)
in SwitchView (created by Navigator)
in Navigator (at create-redux-container.js:93)
in NavigatorReduxWrapper (created by ConnectFunction)
in ConnectFunction (at App.js:48)
in RCTView (at View.js:34)
in View (created by MenuProvider)
in RCTView (at View.js:34)
in View (created by MenuProvider)
in MenuProvider (at App.js:47)
in RCTView (at View.js:34)
in View (at NativeAppearance.tsx:4)
in FallbackAppearanceProvider (at src/index.tsx:70)
in AppearanceProvider (at App.js:46)
in Provider (at App.js:45)
in App (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
I have tried things that other articles and stackoverflow requests have mentioned, but no luck so far. Somewhat new to React Native, so could be missing something easy.
Another permutation of the error:
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.
Check the render method of `SmsAuthenticationScreen`.
This error is located at:
in RCTView (at View.js:34)
in View (at SmsAuthenticationScreen.js:339)
in SmsAuthenticationScreen (created by ConnectFunction)
in ConnectFunction (created by SceneView)
in SceneView (created by CardContainer)
in RCTView (at View.js:34)
in View (created by CardContainer)
in RCTView (at View.js:34)
in View (created by CardContainer)
in RCTView (at View.js:34)
in View (created by ForwardRef(CardSheet))
in ForwardRef(CardSheet) (created by Card)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (created by PanGestureHandler)
in PanGestureHandler (created by PanGestureHandler)
in PanGestureHandler (created by Card)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (created by Card)
in RCTView (at View.js:34)
in View (created by Card)
in Card (created by CardContainer)
in CardContainer (created by Context.Consumer)
in RNSScreen (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at src/index.native.js:111)
in Screen (created by MaybeScreen)
in MaybeScreen (created by Context.Consumer)
in RNSScreenContainer (at src/index.native.js:136)
in ScreenContainer (created by MaybeScreenContainer)
in MaybeScreenContainer (created by Context.Consumer)
in CardStack (created by KeyboardManager)
in KeyboardManager (created by Context.Consumer)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:74)
in SafeAreaProvider (created by Context.Consumer)
in SafeAreaProviderCompat (created by StackView)
in GestureHandlerRootView (at GestureHandlerRootView.android.js:31)
in GestureHandlerRootView (created by StackView)
in StackView (created by StackView)
in StackView
in Unknown (created by Navigator)
in Navigator (created by SceneView)
in SceneView (created by SwitchView)
in SwitchView (created by Navigator)
in Navigator (at create-redux-container.js:93)
in NavigatorReduxWrapper (created by ConnectFunction)
in ConnectFunction (at App.js:48)
in RCTView (at View.js:34)
in View (created by MenuProvider)
in RCTView (at View.js:34)
in View (created by MenuProvider)
in MenuProvider (at App.js:47)
in RCTView (at View.js:34)
in View (at NativeAppearance.tsx:4)
in FallbackAppearanceProvider (at src/index.tsx:70)
in AppearanceProvider (at App.js:46)
in Provider (at App.js:45)
in App (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
Here is the package.json
{
"name": "MyApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start",
"prettier": "prettier --write '*.js' 'src/**/*.js'",
"test": "jest",
"lint": "eslint .",
"android": " cd android && ./gradlew clean && cd .. && react-native run-android",
"ios": "react-native run-ios"
},
"dependencies": {
"@react-native-community/art": "^1.2.0",
"@react-native-community/async-storage": "^1.12.0",
"@react-native-community/cameraroll": "^4.0.0",
"@react-native-community/geolocation": "^2.0.2",
"@react-native-community/masked-view": "^0.1.10",
"@react-native-firebase/app": "^6.7.1",
"@react-native-firebase/auth": "^6.7.1",
"@react-native-firebase/messaging": "^6.7.1",
"@skele/components": "^1.0.0-alpha.40",
"axios": "^0.19.0",
"base-64": "^0.1.0",
"crypto-js": "^3.1.9-1",
"expo-av": "~8.0.0",
"expo-blur": "^8.1.0",
"expo-camera": "^8.0.0",
"expo-constants": "~8.0.0",
"expo-facebook": "~8.0.0",
"expo-file-system": "^8.1.0",
"expo-firebase-recaptcha": "^1.1.3",
"expo-image-picker": "~8.0.1",
"expo-localization": "~8.0.0",
"expo-location": "~8.0.0",
"expo-permissions": "^8.1.0",
"firebase": "7.19.1",
"formik": "^2.1.5",
"i18n-js": "^3.7.1",
"invert-color": "^2.0.0",
"jest-haste-map": "^25.1.0",
"jest-serializer": "^25.1.0",
"jest-worker": "^25.1.0",
"lodash": "^4.17.20",
"lodash.isequal": "^4.5.0",
"lodash.memoize": "^4.1.2",
"mobx": "^5.14.0",
"mobx-react": "^6.3.0",
"moment": "^2.24.0",
"oauth-1.0a": "^2.2.6",
"react": "16.13.1",
"react-native": "0.63.2",
"react-native-actionsheet": "^2.4.2",
"react-native-animatable": "^1.3.3",
"react-native-app-intro-slider": "^3.0.0",
"react-native-appearance": "~0.3.4",
"react-native-autogrow-textinput": "^5.4.0",
"react-native-button": "^3.0.1",
"react-native-cli": "^2.0.1",
"react-native-confirmation-code-field": "^6.5.0",
"react-native-dialog-input": "^1.0.8",
"react-native-fast-image": "^8.3.2",
"react-native-fbsdk": "2.0.0",
"react-native-geocoding": "^0.4.0",
"react-native-gesture-handler": "^1.7.0",
"react-native-get-random-values": "^1.4.0",
"react-native-google-places-autocomplete": "^1.8.0",
"react-native-image-crop-picker": "^0.32.3",
"react-native-image-filter-kit": "^0.7.3",
"react-native-image-picker": "^2.3.3",
"react-native-image-progress": "^1.1.1",
"react-native-image-view": "^2.1.9",
"react-native-indicators": "^0.17.0",
"react-native-iphone-x-helper": "^1.2.1",
"react-native-keyboard-aware-scroll-view": "^0.9.2",
"react-native-keyboard-aware-view": "0.0.14",
"react-native-keyboard-input": "^6.0.0",
"react-native-keyboard-tracking-view": "^5.6.1",
"react-native-localize": "^1.4.1",
"react-native-maps": "0.27.1",
"react-native-modal": "^11.5.6",
"react-native-modal-patch": "git+https://github.com/HarvestProfit/react-native-modal-patch.git",
"react-native-modalbox": "^2.0.0",
"react-native-phone-input": "^0.2.4",
"react-native-popup-menu": "^0.15.9",
"react-native-progress": "^4.1.2",
"react-native-reanimated": "^1.2.0",
"react-native-safe-area-context": "^3.1.7",
"react-native-screens": "^2.10.1",
"react-native-search-box": "0.0.19",
"react-native-slider": "^0.11.0",
"react-native-splash-screen": "^3.2.0",
"react-native-swiper": "^1.6.0-nightly.5",
"react-native-unimodules": "^0.10.1",
"react-native-vector-icons": "7.0.0",
"react-native-video": "^5.0.2",
"react-native-view-more-text": "^2.1.0",
"react-native-webview": "^10.8.2",
"react-navigation": "^4.4.0",
"react-navigation-drawer": "^2.5.0",
"react-navigation-redux-helpers": "^4.0.1",
"react-navigation-stack": "^2.8.2",
"react-navigation-tabs": "^2.9.0",
"react-redux": "^7.2.1",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"remote-redux-devtools": "^0.5.16",
"uuidv4": "^5.0.1"
},
"devDependencies": {
"@babel/core": "^7.11.4",
"@babel/plugin-proposal-decorators": "^7.10.5",
"@babel/runtime": "^7.8.4",
"@react-native-community/eslint-config": "^1.1.0",
"babel-jest": "^25.1.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"eslint": "6.5.1",
"jest": "^25.1.0",
"metro-react-native-babel-preset": "^0.59.0",
"prettier": "2.0.5",
"react-test-renderer": "16.13.1"
},
"jest": {
"preset": "react-native"
}
}
If you upgrade only your react-native version, then a quick cache cleaning and module reset should be fine:
rm -rf node_modules && yarn cache clean && yarn install
From your log, the error seems to appear due to the KeyboardAwareScrollView
module. Upon quick search on the github repo of this module, I found out the following: https://github.com/APSL/react-native-keyboard-aware-scroll-view/issues/443
The issue is still not fixed but there are workarounds available in the above link which you can try. I would just uninstall react-native-keyboard-aware-scroll-view
and install this fork which fixes this issue:
npm i @codler/react-native-keyboard-aware-scroll-view
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With