I've been working on this program and I've recently tried to use some new components from the react-native library like Icon and Header but whenever I try to use them in the render function I get error:
"Invariant Violation: Invariant Violation: 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 really weird to me because I was, and still am, using components like Image, Text, and View without a problem so I don't get why I would be having an issue now with these new components. I'm not sure what I changed in my program to cause something like this to happen.
Only thing I can think of is that "Settings" used to be a default class but it is now not, but that doesn't explain how the old component I was using from the library still work. Keep in mind the other components I imported before like Image and others still work.
Here's and snippet of the offending code:
import React, { Component } from 'react';
import {StyleSheet, Text, View, TouchableHighlight, Image, Header, Icon} from 'react-native';
import { createStackNavigator } from 'react-navigation';
export class Settings extends React.Component {
render(){
return (
<View>
<View style={{height: 55, backgroundColor: '#007ebc'}}>
<View style={{flexDirection: "row", marginLeft: 10}}>
<Icon //<-------USING ICON WILL GIVE ME ERROR
name = 'arrowleft'
/>
<Image source={require("../assets/LogoLrg.png")}
style={{ width: 55, height: 30, marginTop: 10 }}
/>
<Text style={styles.headerText}> Settings </Text>
</View>
</View>
</View>
)
}
I don't think Icon or Header component exists in react-native library.
You can check it in react native website or react-native.js source code.
http://facebook.github.io/react-native/docs/getting-started
Unless I have missed some major update to React Native, you cannot import Header and Icon components from react-native because they don't exist. These components may be a part of some open-source library like react-native-elements or native-base, so you first have to install them:
npm i native-base --save
or,
npm i react-native-elements --save
and then use them:
import { Header, Icon } from 'react-native-elements' //or 'native-base'
RN Elements: Icon, Header
Native Base: Icon, Header
Related
Working thru a React Native tutorial and got to a part on Routing between various components. It looks like it doesnt like the "Menu" component and its asking, as the title says,
Is your component inside NavigationContainer?
As far as I can tell yes. I tried asking the author but this was on Pluralsight and I dont't think they've checked back in ages. I checked their code though, and it works just like I have it. So not sure what may have changed with the framework since that series was made.
Here is the full output when the error pops:
This error is located at:
in Menu (created by Home)
in RCTView (created by View)
in View (created by Home)
in RCTView (created by View)
in View (created by Home)
in Home (created by App)
in App
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in GloboTicket(RootComponent), js engine: hermes
The Menu component (minus StyleSheet)
import React from 'react';
import {View, TouchableOpacity, Text, StyleSheet} from 'react-native';
import {useNavigation} from '#react-navigation/native';
const Menu = () => {
const navigation = useNavigation();
return (
<View style={styles.menu}>
<TouchableOpacity
onPress={navigation.navigate('Tickets')}
style={styles.button}>
<Text style={styles.buttontext}>Events</Text>
</TouchableOpacity>
</View>
);
};
export default Menu;
Code from "Home" where the Menu is used (minus StyleSheet):
import React from 'react';
import {View, Image, Text, StyleSheet} from 'react-native';
import Menu from './Menu';
const Home = props => {
return (
<View style={styles.container}>
<Image
style={styles.globologo}
source={require('./images/globologo.png')}
/>
<Text style={styles.title}>Welcome to GloboTicket</Text>
<Text style={styles.subtitle}>{props.username}</Text>
<Image
style={styles.concertimage}
source={require('./images/concert.jpg')}
/>
<View style={styles.textcontainer}>
<Text style={styles.content}>{introText}</Text>
</View>
<View style={styles.menu}>
<Menu />
</View>
</View>
);
};
App file (where all lies within a NavigationContainer):
import 'react-native-gesture-handler';
import React from 'react';
import { StatusBar } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Home from './Home';
import Tickets from './Tickets';
const Stack = createStackNavigator();
function App(): JSX.Element {
return (
<>
<StatusBar barStyle='dark-content' hidden />
<NavigationContainer>
<Stack.Navigator
initialRouteName='Home'
>
<Stack.Screen
name='Home'
options={{
headerShown: false,
}}
>
{props => <Home {...props} username='Bella' />}
</Stack.Screen>
<Stack.Screen
name='Tickets'
component={Tickets}
options={{
headerTitleAlign: 'center',
headerTitleStyle: { fontFamily: 'Ubuntu-Regular' }
}}
/>
</Stack.Navigator>
</NavigationContainer>
</>
);
}
export default App;
I have checked the documentation to make sure I set it correctly and that I wasnt doing something blatantly wrong, and I cant find anything suggesting that I did.
What I expected was for my code to not have an error I guess? Or at least for the error to be something that tells me what to do in more detail so I can fix it. There is an image that shows on the emulator where it throws the error, but its literally where the error is thrown and not what caused it.
Seen Here
I have seen people mention the below, but I seem to have this covered to my knowledge:
useNavigation only works if your component is inside of a NavigationContainer and a Navigator
I have also looked at this page, as multiple SO answers have suggested. I dont truly understand it, but from a surface level I dont think it applies if I AM navigating with navigation prop:
Link Here
I cant just get rid of the component, thats not a viable option. So I'm hoping someone here has some advice.
Stumbled into an answer. Not sure if it is THE answer but it worked. Detailed below:
In my Menu file, I had this:
onPress={navigation.navigate('Tickets')}
But I suppose what it wanted, or what ended up working at least was:
onPress={navigation.navigate(Tickets)}
Notice the lack of single quotes.
What I did was import the Tickets component to the Menu file and used that for the Navigate call.
UPDATE TO ADD METHOD #2
It's been a few days, but I found another answer. In my App file, you can see I named the components with single quotes. Changing them to double quotes fixed this as well, for me at least.
Example:
<Stack.Screen
name='Tickets' // CHANGE THIS TO name="Tickets"
component={Tickets}
options={{
headerTitleAlign: 'center',
headerTitleStyle: { fontFamily: 'Ubuntu-Regular' }
}}
/>
I upgraded native-base library from 2.13.14 to 3.0.3 and wrapped my App.js content in NativeBaseProvider. Here is the error I got after doing this:
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.
--
My Code:
import React, {useEffect} from 'react';
import {I18nManager, ActivityIndicator} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {NativeBaseProvider, Container} from 'native-base';
import TrackPlayer from 'react-native-track-player';
import {PlayerContextProvider} from './contexts/PlayerContext';
import MainStackNavigator from './Navigators/MainStackNavigator';
const App = () => {
const [isReady, setIsReady] = React.useState(false);
useEffect(() => {
TrackPlayer.setupPlayer().then(() => {
console.log('player is setup');
TrackPlayer.updateOptions({
capabilities: [
TrackPlayer.CAPABILITY_PLAY,
TrackPlayer.CAPABILITY_PAUSE,
TrackPlayer.CAPABILITY_STOP,
TrackPlayer.CAPABILITY_JUMP_BACKWARD,
TrackPlayer.CAPABILITY_JUMP_FORWARD,
],
jumpInterval: 30,
});
setIsReady(true);
});
}, []);
return (
<NativeBaseProvider>
<Container>
{isReady ? (
<PlayerContextProvider>
<NavigationContainer>
<MainStackNavigator />
</NavigationContainer>
</PlayerContextProvider>
) : (
<Container>
<ActivityIndicator />
</Container>
)}
</Container>
</NativeBaseProvider>
);
};
I18nManager.forceRTL(true);
export default App;
I did found the root cause of this problem (in my case). The approach was to go down the navigator structure (in your case start with MainStackNavigator) and replace the rendered component with the example code from https://docs.nativebase.io/setup-provider until it breaks:
function Test() {
return (
<Box flex={1} bg="#fff" alignItems="center" justifyContent="center">
<Text>Open up App.js to start working on your app!</Text>
</Box>
)
}
In my case it lead me to a component which was using deprecated native-base elements from v2. Sadly there is no good deprecation guide or migration guide which tells you how to upgrade from v2 to v3.
So following this approach might lead out of this situation (the error message is not really helpful). Keep an eye on the following deprecated components or functions and replace them as follows:
Header -> use HStack docs.nativebase.io/3.0.0/migration/Header
Body -> use Box or Container (not documented)
Left -> use Center or remove (not documented)
Right -> use Center or remove (not documented)
getTheme -> use extendTheme docs.nativebase.io/setup-provider#add-custom-theme-optional
StyleProvider -> use NativeBaseProvider docs.nativebase.io/setup-provider
This is my list of deprecated components so far. In addition here are some update guides for
Icon docs.nativebase.io/3.0.0/migration/Icon
Button docs.nativebase.io/3.0.0/migration/Button
and there are a lot more to be found on this index page https://docs.nativebase.io/3.0.0/migration/
I hope It helps you solving this problem.
Have a try to move the forceRTL method inside the useEffect of the app initialization.
like :
useEffect(() => {
I18nManager.forceRTL(true); // here..
TrackPlayer.setupPlayer().then(() => {
Might it will help you.
I've been using the library to create bottom sheet modals for my react native app, but it's doesn't seem to work on Android, but on iOS it does. I used the same backdrop component and handle component suggested in the docs, and everything is contained is the provider, and SafeAreaView
my package.json includes
"#gorhom/bottom-sheet": "^3.6.5",
"react-native-reanimated": "^2.0.0",
and the code is structured like this:
<BottomSheetModal ref={reference_settings}
index = {1}
enableOverDrag={true}
onChange = {(index) => { if(index === 0) { reference_settings.current.dismiss(); } }}
snapPoints = {[-1, '50%', '70%']}
backdropComponent={Backdrop}
handleComponent ={(props) => (<Belt {...props} />)}
style ={styles.sheet}
>
<BottomSheetView style={[styles.content]}>
<View style={{ width, height: '100%', overflow: 'hidden', backgroundColor: scheme === 'dark' ? '#000' : '#FFF', paddingHorizontal: 10 }}>
// the functions inside
</View>
</BottomSheetView>
</BottomSheetModal>
I used the right configuration for babel for react-native-reanimated including the plugin, but it shows up and then I can't drag to close.
I know it's a bit late to answer for you but I would like to add for others. Assuming you already installed react-native-gesture-handler you should also add some lines of code to your MainActivity.java.
Don't forget to wrap your Root App Component like this in the index.js file
place the the import statement at the top of index.js
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
import {AppRegistry} from 'react-native';
AppRegistry.registerComponent(appName, () => gestureHandlerRootHOC(App));
more details
When I am using Navigator from react native I am getting an error. The error is:
Warning: React.createElement: 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 your code at App.js:11.
My code is:
import React, { Component } from 'react';
import {
Text,
Navigator,
TouchableHighlight
} from 'react-native';
export default class App extends Component {
render() {
return (
<Navigator
initialRoute={{ title: 'Awesome Scene', index: 0 }}
renderScene={(route, navigator) => (
<Text>Hello {route.title}!</Text>
)}
style={{ padding: 100 }}
/>
);
}
}
I followed this tutorial: https://reactnative.dev/docs/0.43/navigator
Can someone please help me in this. Is there something wrong in documentation?
This code example is from react doc version 0.43. After that "Navigator" was removed.
If you do not care about backward compatibility then I would suggest following current documentation (0.63). In the latest version, there is more simple solution is given.
My container class:
import React from 'react';
import {View} from 'react-native';
const Cont = (props) => {
return(
<View style={styles.cStyle}>
{props.children}
</View>
);
};
const styles = {
cStyle: {
borderWidth: 1,
borderRadius: 2,
borderColor: '#fff',
borderBottomWidth: 0,
elevation: 10,
marginLeft: 5,
marginRight: 5,
marginTop: 10
}
};
export default Cont;
Now the class that uses this component:
import React from 'react';
import {Text} from 'react-native';
import Cont from './Cont';
const Det = (props) => {
return(
<Cont>
<Text>{props.alb.title}</Text>
</Cont>
);
};
export default Det;
I don't think I need to provide the index.js, since all I'm doing related to the subject in matter is calling a self closing tag of the object. I have no idea why my styles are not being applied. I checked everything I thought I could of have checked. Any ideas? Any support is appreciated.
PS: I was expecting <Text /> childs to inherit my styles
PS2: Also I'm not sure this is really 'inheritance'. Because actually the styles should affect every <View> from my class and then consequently the children that is INSIDE my <View> tags
I'd like to answer my own question regarding this issue because there might be other persons struggling now or in the future, and would not know quite what to do, hopefully this answer will help them.
There was no error in my code, at least not in the classes I posted above. And EVERY <Text> children should be inside a styled <View>, which was my intention at first. So I had made a typo when calling the class in the entry js file. But, somehow (yes this defies my current React Native knowledge which is already little) the app was still compiling but not styling ANYTHING. Only after I restarted not only the server in the terminal but also the simulator, is that I received the bug which I could finnally debug. (Unexpected char 'blabla' in Line X). After fixing it my styles were applied. But the craziest thing is: It was either compiling with an unexpected character (which seems impossible to me) or compiling a past version of my App. Now, this sounds absolutely crazy to me and I will be reporting it on React Native forums and Android Studio. Thanks for all the help.
EDIT: React Native forums topic on the issue: http://discuss.nativebase.io/t/android-simulator-compiling-wrong-code/1183
Regular styles behave differently in react-native compared to CSS in say, the web-browser. There's no concept of style inheritance by default in react-native, so styling that you apply to <Cont /> won't be inherited by the children of <Cont /> (ie your <Text> elements).
When styling with react, you'll typically need to apply styles directly to all components that you want to tweak the appearance of:
<Cont>
{ /* custom styling must be applied to all components that you
want to tweak */ }
<Text style={{ color : 'red' }}>{props.alb.title}</Text>
</Cont>
Something to also keep in mind is that different element types (<Text/> , <View />, etc) sometimes only support a limited subset of styling options. For example, see the styling documentation for <Text /> for an overview of the styling options that the <Text /> element type supports.