Am trying to start playing with React Native now. And I come from web development field.
Since start, am trying to organize my folder structure so that it would be easy for me to understand and make modifications later.
Right now the folder structure is as follows:
/screens
HomeScreen.js
ProfileScreen.js
/navigation
MainNavigation.js
App.js
... etc
Am using Expo CLI as this is my first time working on React Native.
/navigation/MainNavigation.js
import React from 'react';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import HomeScreen from '../screens/HomeScreen';
import ProfileScreen from '../screens/ProfileScreen';
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen,
},
{
initialRouteName: 'Home',
}
);
const AppContainer = createAppContainer(RootStack);
export default class Navigation extends React.Component {
render() {
return (
<AppContainer />
);
}
}
/screens/HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button, TouchableOpacity } from 'react-native';
export default function HomeScreen() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.blue_btn} onPress={() => this.props.navigation.navigate('Profile')}>
<Text style={styles.white_text}>Profile</Text>
</TouchableOpacity>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
HomeScreen.navigationOptions = {
header: null,
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
blue_btn: {
backgroundColor: '#13baa8',
padding: 10,
},
white_text: {
color: 'white',
}
});
/screens/ProfileScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default function ProfileScreen() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
ProfileScreen.navigationOptions = {
title: 'Profile',
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
App.js
import React from 'react';
import Navigation from './navigation/MainNavigation';
export default class App extends React.Component {
render() {
return (
<Navigation />
);
}
}
When I click on the Profile button in the HOME Screen, it is showing this message:
undefined is not an object(evaluating '_this.props.navigation')
Thank you
import React, { Component } from 'react';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import ScreenOne from './ScreenOne';
import ScreenTwo from './ScreenTwo';
const NavStack = createStackNavigator({
ScreenOne: {
screen: ScreenOne,
},
ScreenTwo: {
screen: ScreenTwo,
},
});
const App = createAppContainer(NavStack);
export default App;
Related
I have a big problem with my code at the moment, and I know, there is a lot of request with the same issue as mine. I tried a lot of the solutions, but NOTHING helped.
Maybe someone can help me :)
I get the issue in the Title mentionend:
Error: The component for route 'Home' must be a React component. For
example:
import MyScreen from './MyScreen'; ... Home: MyScreen, }
You can also use a navigator:
import MyNavigator from './MyNavigator'; ... Home: MyNavigator, }
This is my code in the specified files:
App.js
import React from 'react'; import { View, Text, Button } from 'react-native'; import { createAppContainer } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack';
import Home from './src/Home'; import Profile from './src/Profile';
const Navigator = createStackNavigator({ Home: { screen: Home }, Profile: { screen: Profile }, }, { initialRouteName: 'Home', });
const App = createAppContainer(Navigator);
export default App;
Home.js
import React from 'react'; import { StyleSheet, View, Button } from 'react-native';
export default class Home extends React.Component {
static navigationOptions = {
title: 'Home', };
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Button
title="Go to profile screen"
onPress={() => navigate(
'Profile', { name: 'Jane' }
)}
/>
</View>
);
}
}
const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center' } });
Profile.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
export default class Profile extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('name'),
};
};
render() {
const { navigate, state } = this.props.navigation;
return (
<View style={styles.container}>
<Text>Hello {state.params.name}</Text>
<Button
title="Go to home screen"
onPress={() => navigate('Home')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
Please make sure that you are having the following structure in your project:
App.js in your project folder. Home.js and Profile.js in the src folder.
App.js (in ./ folder)
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import Home from './src/Home';
import Profile from './src/Profile';
const Navigator = createStackNavigator({ Home: { screen: Home }, Profile: { screen: Profile }, }, { initialRouteName: 'Home', });
const App = createAppContainer(Navigator);
export default App;
Home.js (in ./src folder)
import React from 'react'; import { StyleSheet, View, Button } from 'react-native';
export default class Home extends React.Component {
static navigationOptions = {
title: 'Home', };
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Button
title="Go to profile screen"
onPress={() => navigate(
'Profile', { name: 'Jane' }
)}
/>
</View>
);
}
}
const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center' } });
Profile.js (in ./src folder)
import React, { Component } from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
export default class Profile extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('name'),
};
};
render() {
const { navigate, state } = this.props.navigation;
return (
<View style={styles.container}>
<Text>Hello {state.params.name}</Text>
<Button
title="Go to home screen"
onPress={() => navigate('Home')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
If you place all the files correctly, it will WORK.
Please click the link below to see the result:
http://www.createchhk.com/2020_12_30_01_56_22.mp4
I'm having an issue with my react-navigation-stack, I believe it could be a problem with dependencies, but I'm not sure if that's it. I am simply trying to have some text redirect to another page. If there is code that is irrelevant to the issue, such as a button, I apologize as I am trying to learn react native. The problem is being pointed at homeStack.js at the first import, "import { createStackNavigator } from '#react-navigation/stack';" , but previously I just used react-navigation-stack there, which I believe was a part of old dependencies, but it gave me a module not found error at first, which changed to what I have now when I put #react-navigation/stack instead. I was learning from a video tutorial, but the code from the tutorial was not compiling. I redownloaded react navigation multiple times and have tried some thing that did not work. I will post my code below and would really appreciate help and input as to what can help my problem. Thanks you!
Picture of error
homeStack.js
import { createStackNavigator } from '#react-navigation/stack';
//import { createAppContainer } from '#react-navigation/native';
//import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Home from '../screens/home';
import ReviewDetails from '../screens/reviewDetails';
const screens = {
Home: {
screen: Home,
},
ReviewDetails: {
screen: ReviewDetails,
},
};
// home stack navigator screens
const HomeStack = createStackNavigator(screens);
export default createAppContainer(HomeStack);
home.js
import React from 'react';
import { StyleSheet, View, Text, } from 'react-native';
import { globalStyles } from '../styles/global';
export default function Home() {
return (
<View style={globalStyles.container}>
<Text style={globalStyles.titleText}>Home Screen</Text>
</View>
);
}
App.js
//import React from 'react';
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import Buttonwithbackground from './src/Buttonwithbackground';
import { StackNavigator } from 'react-navigation';
//import Expo from 'expo';
//import Screen from 'screen2';
import { AppLoading } from 'expo';
import Navigator from './routes/homeStack';
import { render } from 'react-dom';
//
//import {Link} from 'react-router-dom';
class HomeScreen extends React.Component{
static NavigationOptions = {
title: 'Home',
};
render(){
const { navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Text
onPress= { ()=> navigate('Home') }>Navigate to Profile
</Text>
</View>
);
}
}
class ProfileScreen extends React.Component{
static NavigationOptions = {
title: 'Profile',
};
render(){
const { navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Text
onPress= { ()=> navigate('Profile') }>Navigate to Profile
</Text>
</View>
);
}
}
//export default function App() {
export default class App extends Component {
editUser = () => {
this.props.navigation.navigate("Screen");
// this.navigation.navigate("screen2");
// window.location.href = 'screen2';
};
editUser2 = () => {
//if the second button is clicked, it will redirect to yahoo.com
window.location.href="http://yahoo.com"
};
render(){
return (
<View style={styles.container}>
<Image
style={{width: 350, height: 200}}
source = {require('./assets/dolanduckjoker.jpg')}
/>
<Navigator />
<Buttonwithbackground text='Login' color='black' onPress={this.editUser2}/>
<p><br/></p>
<Button title='Login' color='black' onPress={this.editUser2}/>
<Button title='Login' color='black' onPress={() => navigation.navigate('screen2.js')}/>
<p><br/></p>
<Button
style={styles.cancelButton}
onPress={this.editUser}
title="Register"
color="#343434"
accessibilityLabel="Register a User."/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 32,
textAlign: 'center',
margin: 10,
},
});
The error says what's wrong -
Object(...) is not a function
createStackNavigator expects a function and you are passing an object to it as a parameter. According to docs
Your code should look like -
import { createStackNavigator } from '#react-navigation/stack';
//import { createAppContainer } from '#react-navigation/native';
//import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Home from '../screens/home';
import ReviewDetails from '../screens/reviewDetails';
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="ReviewDetails" component={ReviewDetails} />
</Stack.Navigator>
);
}
export default MyStack; //you need to render this
Now in your root file, It should be something like this (excluding your additional code) -
import { createStackNavigator } from '#react-navigation/stack';
import MyStack from "yourPath";
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
I am new to react native and I have been trying to create a header and pull out menu using createDrawerNavigator.
When running my code I get the following error.
Error: The component for route 'Home' must be a React component. For example:
import MyScreen from './MyScreen';
Home: MyScreen,
}
You can also use a navigator:
import MyNavigator from './MyNavigator';
Home: MyNavigator,
}
Here is my app.js file:
import React from 'react';
import { Button, View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import MyDrawerNavigator from './components/MyDrawerNavigator';
const MyApp = createAppContainer(MyDrawerNavigator);
export default class App extends React.Component {
render() {
return <MyApp />;
}
}
My HomeScreen.js file
import React from 'react';
import { Text, Button } from 'react-native';
import LogoTitle from './LogoTitle';
class MyHomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: <LogoTitle />,
headerLeft: (
<Button
onPress={() => this.props.navigation.navigate('DrawerToggle')}
title={'Menu'}
/>
),
};
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
export default MyHomeScreen;
My MyDrawerNavigator.js file
import React from 'react';
import { Button, Platform, Image, View, Text } from 'react-native';
import { createDrawerNavigator } from 'react-navigation-drawer';
import MyHomeScreen from './HomeScreen';
import DetailsScreen from './DetailScreen';
const MyDrawerNavigator = createDrawerNavigator(
{
Home: MyHomeScreen,
Details: DetailsScreen,
}, {
drawerPosition: 'right',
contentOptions: {
activeTintColor: '#000',
},
});
export default MyDrawerNavigator
The are 2 problems here:
1) You are not exporting your MyDrawerNavigator just add:
export default MyDrawerNavigator
to your MyDrawerNavigator.js file
2) You are not exporting your HomeScreen. You'll have to create a separate file for it, like you did with DetailsScreen.
The HomeScreen.js file would look like:
class MyHomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: <LogoTitle />,
headerLeft: (
<Button
onPress={() => this.props.navigation.navigate('DrawerToggle')}
title={'Menu'}
/>
),
};
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
You NEED to add a render inside of your screens
I have created a MenuButton as well as 2 other pages one of them being the settingScreen, where I have imported the MenuButton within both files and they seem to be working fine. But when I import the setting Screen on the DrawerNavigator file it doesn't recognize MenuButton
Failed to load bundle(http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false) with error:(Unable to resolve module `./Menu/MenuButton` from `/Users/camillebasbous/Project/Menu/SettingScreen.js`: The module `./Menu/MenuButton` could not be found from `/Users/camillebasbous/Project/Menu/SettingScreen.js`. Indeed, none of these files exist:
* `/Users/camillebasbous/Project/Menu/Menu/MenuButton(.native||.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)`
* `/Users/camillebasbous/Project/Menu/Menu/MenuButton/index(.native||.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)` (null))
__38-[RCTCxxBridge loadSource:onProgress:]_block_invoke.228
RCTCxxBridge.mm:414
___ZL36attemptAsynchronousLoadOfBundleAtURLP5NSURLU13block_pointerFvP18RCTLoadingProgressEU13block_pointerFvP7NSErrorP9RCTSourceE_block_invoke.118
__80-[RCTMultipartDataTask URLSession:streamTask:didBecomeInputStream:outputStream:]_block_invoke
-[RCTMultipartStreamReader emitChunk:headers:callback:done:]
-[RCTMultipartStreamReader readAllPartsWithCompletionCallback:progressCallback:]
-[RCTMultipartDataTask URLSession:streamTask:didBecomeInputStream:outputStream:]
__88-[NSURLSession delegate_streamTask:didBecomeInputStream:outputStream:completionHandler:]_block_invoke
__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__
-[NSBlockOperation main]
-[__NSOperationInternal _start:]
__NSOQSchedule_f
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_continuation_pop
_dispatch_async_redirect_invoke
_dispatch_root_queue_drain
_dispatch_worker_thread2
_pthread_wqthread
start_wqthread
I have tried testing ou the other page and after a few tests I realized that the presence of the imported MenuButton within these pages is what is forcing an error Is there a way to import a file that has imported another to be displayed or do I have to import both of them within drawerNavigation and if so how to structure the code. Thanks
Drawer Navigation code:
import * as React from 'react';
import { Text, View, Image, ScrollView, StyleSheet } from 'react-native';
import {
createDrawerNavigator,
createAppContainer,
DrawerItems,
SafeAreaView,
} from 'react-navigation';
import SettingScreen from './Menu/SettingScreen'
class Home extends React.Component {
static navigationOptions = {
title: 'Home',
};
render() {
return (
<View style={styles.container}>
<SettingScreen/>
</View>
);
}
}
const Navigator = createDrawerNavigator(
{
Home,
},
{
//drawerType: 'back',
// drawerPosition: 'right',
// drawerWidth: 200,
drawerBackgroundColor: '#262A2C',
// contentComponent: CustomDrawerContentComponent
}
);
export default createAppContainer(Navigator);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
}
});
SettingScreen code:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MenuButton from './Menu/MenuButton'
export default class SettingScreen extends React.Component{
render(){
return(
<View style={styles.container}>
<MenuButton/>
<Text style={styles.text}>Settings</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'rgba(215,215,215,1)',
alignItems: 'center',
justifyContent: 'center',
},
text:{
fontSize: 30,
}
});
MenuButton code:
import React from 'react';
import {AppRegistry, StyleSheet, View} from "react-native" ;
import Icon from 'react-native-vector-icons/Ionicons'
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'
export default class MenuButton extends React.Component {
render() {
return(
<View >
<Icon name= "ios-menu" size={wp('12%')} color='#9B9B9B' style={{position: 'absolute', top: wp('-82.5%'), left: wp('-46%'), }}></Icon>
</View>
)
}
}
AppRegistry.registerComponent('Menu', () => FixedDimensionsBasics);
The path you are using on import is relative to your file. So, as everything is on the same folder, you must correct the import path like that:
On Drawer Navigator code
import SettingScreen from './SettingScreen'
On SettingScreen code
import MenuButton from './MenuButton'
I have following problem:
I created new StackNavigator in App.js and in Login.js in navigationOptions I added new title, but when I run the app on my iPhone through Expo, then I don't see the title.
I've already tried to update the npm, to update expo, to reinstall node_modules, instead of AppRegistry I have tried to use Expo.registerRootComponent, but nothing worked - I still don't have a title.
How can I fix it?
App.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import { createStackNavigator } from 'react-navigation';
import Login from './src/screens/Login';
import Secured from './src/screens/Secured';
import Register from './src/screens/Register';
export default class ReactNativeStormpath extends Component {
state = {
isLoggedIn: false
}
render() {
if (this.state.isLoggedIn)
return <Secured onLogoutPress={() => this.setState({isLoggedIn: false})} />;
else
return <Login onLoginPress={() => this.setState({isLoggedIn: true})} />;
}
}
const LifeStorm = createStackNavigator({
Login: { screen: Login },
Register: { screen: Register },
Secured: { screen: Secured },
});
AppRegistry.registerComponent('LifeStorm', () => LifeStorm);
Login.js
import Expo from 'expo';
import React, { Component } from "react";
import { AppRegistry, StyleSheet, Text, TextInput, View, Button } from "react-native";
import { navigation } from 'react-navigation';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
},
});
export default class Login extends Component {
static navigationOptions = {
header: { visible:true },
title: "Log In",
};
render() {
return (
<View style={styles.container}>
<TextInput placeholder="Username" />
<TextInput placeholder="Password" />
<Button onPress={this.props.onLoginPress} title="Submit" />
<Button onPress={this.props.onLoginPress} title = "Register" />
</View>
);
}
}
AppRegistry.registerComponent('Login', () => LifeStorm);