How do you load a screen from an external .js file? - javascript

My goal is to render my homescreen from an external .js file called home.js. This .js file is located in a directory below root project directory in a a folder called "screens". I am having trouble rendering the contents in that home.js file. If I move the code from my home.js file back into the app.js file it works perfectly fine. I am trying to take a modular approach since this is best practice and would rather not stuff everything into the app.js file. I plan on creating more screens in the near future but am trying to wrap my mind around the basics first.
My current code in the app.js file
// In App.js in a new project
import React from "react";
import { View, Text } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";
import HomeScreen from './screens/home.js';
/*
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Details Screen</Text>
</View>
);
}
}
*/
export default createAppContainer(AppNavigator);
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
//Details: DetailsScreen
},
{
initialRouteName: "Home"
}
);
The code in my home.js file is
import React from "react";
import { View, Text } from "react-native";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
Edit 1:
My current error is
undefined is not an object (evaluating 'Component.router')
createNavigationContainer
C:\Repos\demoProject\node_modules#react-navigation\native\src\createAppContainer.js:88:30
<unknown>
C:\Repos\demoProject\App.js:24:34
loadModuleImplementation
C:\Repos\demoProject\node_modules\metro\src\lib\polyfills\require.js:331:6
<unknown>
C:\Repos\demoProject\node_modules\expo\AppEntry.js:4
loadModuleImplementation
C:\Repos\demoProject\node_modules\metro\src\lib\polyfills\require.js:331:6
guardedLoadModule
C:\Repos\demoProject\node_modules\metro\src\lib\polyfills\require.js:197:45
global code
<unknown file>:0

You're not exporting your HomeScreen component, you can do this by adding an export default infront of the class definition, or underneath.
export default class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
Or
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
export default HomeScreen
You're also attempting to export AppNavigator before it is instantiated. You need to move the export below.
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
//Details: DetailsScreen
},
{
initialRouteName: "Home"
}
);
export default createAppContainer(AppNavigator);

Related

Class or function components in react-native to inject store?

I'm new to react-native and trying to set up my app with mobx for state management, when trying to inject rootStore into my HomeScreen component I get the following error:
Error: C:\xampp\htdocs\second-try\screens\HomeScreen.js: Leading decorators must be attached to a class declaration
This is my component, as you see I'm suing function based component and I get a warning, but how can I use components ass Class and inject mobx stre into my react-native component.
My HomeScreen file:
import * as React from 'react';
import { StatusBar } from 'expo-status-bar';
import { View, Text, StyleSheet } from 'react-native';
#inject(stores => ({
postStore: rootStore.postStore,
//authStore: rootStore.authStore,
})
)
//ERROR IS RIGHT
#observer
const HomeScreen = function()
{
return (
<View style={styles.container}>
<Text>{postStore.postMessage}</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default HomeScreen;

react-navigation - createBottomTabNavigator not working

Hello I am making a react native app with expo. Following is my app.js file:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {createBottomTabNavigator} from 'react-navigation';
import WelcomeScreen from "./screens/WelcomeScreen";
import AuthScreen from "./screens/AuthScreen";
export default class App extends React.Component {
render() {
const MainNavigator = createBottomTabNavigator({
Welcome: WelcomeScreen,
Auth: AuthScreen
});
return (
<View style={styles.container}>
<MainNavigator/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
and following is my package.json file:
{
"main": "node_modules/expo/AppEntry.js",
"private": true,
"dependencies": {
"expo": "^28.0.0",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
"react-navigation": "^2.6.2"
}
}
The app is running without any errors but it does not display the bottom navigation tab! I have checked the syntax from the official documentation as well and i fear it may be due to version of react-navigation.
Any help would be appreciated.
Following is my welcomescreen component file:
import React, {Component} from 'react';
import {Text, View} from "react-native";
class WelcomeScreen extends Component{
render(){
return(
<View>
<Text>
Hello this is working!
</Text>
</View>
);
}
}
export default WelcomeScreen;
auth component is also same except the change of name.
Version is not the issue. The issue is with the custom StyleSheet and <View/> Component
You can View the edited app here
In case u want to try in uer app package.json is:
{
"dependencies": {
"#expo/vector-icons": "6.2.1",
"react-native-elements": "0.18.5",
"react-navigation": "^2.6.2"
}
}
and App.js is:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation'; // Version can be specified in package.json
class AuthScreen extends React.Component{
render(){
return(
<View>
<Text>
AuthScreen Works!
</Text>
</View>
);
}
}
class WelcomeScreen extends React.Component{
render(){
return(
<View>
<Text>
Hello this is working!
</Text>
</View>
);
}
}
export default class App extends React.Component {
render() {
const MainNavigator = createBottomTabNavigator({
Auth: { screen: AuthScreen },
Welcome: { screen: WelcomeScreen },
});
// return (
// <View style={styles.container}>
// <MainNavigator/>
// </View>
// );
return <MainNavigator/>
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Try to have a stack navigator as your first screen and then try to load Welcome screen and Other screen as Bottom Tab Navigator, I have used this structure in many of my apps try this https://github.com/davekedar/React-Navigation-V2-Authflow
I solved this problem by upgrading to
"react-navigation": "^2.13.0"
Encountered this today with "react-navigation": "^4.3.9".
Fixed by setting <View style={{ flex: 1 }}> instead of just <View>. This problem does not occur if you wrap the navigator in something other than <View> (i.e. <Fragment>).
https://github.com/react-navigation/react-navigation/issues/8449
https://reactnavigation.org/docs/troubleshooting/#nothing-is-visible-on-the-screen-after-adding-a-view

react native unexpected token stylesheet

There is my code & the error below. I made some changes in the App.js file, & since then this issue has shown up. I had my router setup in this file originally, but then decided to move. I've tried other styles & it doesn't work either.
App.js
import React from 'react';
import { StyleSheet, Text, View, Navigator } from 'react-native';
import { Fonts } from './src/utils/Fonts';
import Menu from './app/components/Menu';
import Page from './app/components/Page';
import Router from './app/components/Router';
export default class App extends React.Component {
render() {
return (
<View style={styles.fonts}>
<Menu />
</View>
);
}
}
const styles = StyleSheet.create({
fonts: {
fontSize: 30,
fontWeight: 12,
fontFamily: Fonts.Baloo
},
});
Error
I had different styles & code on the Menu component before this issue & it worked fine, but now even when I make changes it doesn't go back to the original, just shows this same error.
Menu.js
import React from 'react';
import {
StyleSheet,
Text,
Image,
MenuItem,
Font,
View,
TextInput,
TouchableOpacity
} from 'react-native';
import { Actions } from 'react-native-router-flux';
export default class Menu extends React.Component {
render() {
return (
<View style={styles.container}>
<Text
style={styles.fonts}
onPress={() => Actions.page()}>
Navvi
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#000',
},
});
I already commented it, but this is how your code should look like (in Menu.js):
export default class Menu extends React.Component {
render() {
return (
<View style={styles.container}>
<Text
style={styles.fonts}
onPress={() => Actions.page()}
>
{"Navvi"}
</Text>
</View>
);
}
}

Why am I getting "undefined is not an object (evaluating PropTypes.shape)"?

Whenever I try to run my iOS simulator, I'm getting that error. All modules are installed, file path to my picture is correct, no errors being thrown within my IDE except for the one that's appearing in my simulator. Picture below of error.
Here's Login.js:
import React, {Component} from 'react';
import {StyleSheet, TextInput, Text, TouchableOpacity, KeyboardAvoidingView} from 'react-native';
class Login extends Component {
onButtonPress() {
this.props.navigator.push({
id: 'CreateAccount'
});
}
render() {
return(
<KeyboardAvoidingView behavior={"padding"} style={styles.container}>
<TextInput
style={styles.input}
returnKeyType={"next"}
keyboardType={"email-address"}
autoCorrect={false}
placeholder={"Email"}
/>
<TextInput
style={styles.input}
returnKeyType={"go"}
placeholder={"Password"}
secureTextEntry
/>
<TouchableOpacity>
<Text style={styles.loginAndCA}>Login</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.onButtonPress.bind(this)}>
<Text style={styles.loginAndCA}>Create Account</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
padding: 20 // Length of text input boxes.
},
input: {
backgroundColor: '#DAE5FF',
padding: 20,
paddingHorizontal: 15,
marginBottom: 10,
borderRadius: 15
},
loginAndCA: {
fontSize: 40,
textAlign: 'center',
color: 'white',
fontFamily: 'Bodoni 72 Smallcaps',
paddingHorizontal: 10
}
});
export default Login;
Here's BackGround.js:
import React, {Component} from 'react';
import {StyleSheet, Image, View, Text} from 'react-native';
import Login from './Login';
class BackGround extends Component {
render() {
return(
<View style={styles.first}>
<Image style={styles.container} source={require('../pictures/smoke.jpg')}>
<View style={styles.second}>
<View>
<Text style={styles.title}>My App</Text>
</View>
<Login/>
</View>
</Image>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
width: null,
height: null,
backgroundColor: 'rgba(0,0,0,0)'
},
first: {
flex: 1
},
second: {
paddingTop: 290 // Moves both <TextInput> boxes down.
},
title: {
fontSize: 34,
textAlign: 'center',
justifyContent: 'center',
flexDirection: 'row',
fontFamily: 'Bodoni 72'
}
// movementTitle: {
// paddingBottom: 34
// }
});
export default BackGround;
Here's CreateAccount.js:
import React, {Component} from 'react';
import {Text} from 'react-native';
class CreateAccount extends Component {
render() {
return(
<Text>Must get to this page</Text>
);
}
}
export default CreateAccount;
Here's index.ios.js:
import React, {Component} from 'react';
import {View, StyleSheet, AppRegistry} from 'react-native';
import {Navigator} from 'react-native-deprecated-custom-components';
import BackGround from './components/BackGround';
import Login from "./components/Login";
import CreateAccount from "./components/CreateAccount";
export default class App extends Component {
render() {
return(
<View style={styles.back}>
<BackGround/>
<Navigator
initialRoute={{id: 'Login'}}
renderScene={this.navigatorRenderScene}
/>
</View>
);
}
navigatorRenderScene() {
_navigator = navigator;
switch(route.id) {
case 'Login':
return (<Login navigator={navigator} title="Login"/>);
case 'CreateAccount':
return (<CreateAccount navigator={navigator} title="Create Account" />);
}
}
}
const styles = StyleSheet.create({
back: {
flex: 1
}
});
AppRegistry.registerComponent('dendroApp', () => dendroApp);
React recently removed PropTypes from their core library as of React 15.5.
Add the line
import PropTypes from 'prop-types';
And call your proptypes directly from that.
It seems PropTypes is undefined. I don't see it declared anywhere in your code. You have to import it via a separate module as shown in the documents: PropTypes.
Update:
Perhaps a library you are using is using the now deprecated/non-supported React.PropTypes. I recommend using a more up to date library or actually going into the library and updating the package so it uses the new PropTypes from the separate package instead of React.PropTypes. This should fix your problem
Yes definitely, if you upgrade react: 15 or higher then you have to add import PropTypes from 'prop-types';
But recently I faced the same issue in "react": "16.0.0-beta.5" after I changed
"dependencies": {
"react": "16.0.0-alpha.12"
},
"devDependencies": {
"react-test-renderer": "16.0.0-alpha.12"
}
Then it found working fine. Hope it helps!

Why am I getting this Transform error in my iOS simulator?

At first, I was using Expo to run my projects on my physical device which means that it doesn't come with an index.ios.js and index.android.js files upon creating a project (All you get is an App.js file which is equivalent to the aforementioned files).
I then copy and pasted my files/code into a normal React Native project (not Expo) which means now I do have index.ios.js and index.android.js files. Specifically, I copy & pasted whatever's in App.js into index.ios.js hoping it carries out the same functionality.
I have no idea why it's throwing this me error upon hitting Run to see what will show up on my iOS simulator.
Picture of error included below.
Transform Error
Here's index.ios.js:
import React, {Component} from 'react';
import {View, StyleSheet} from 'react-native';
import {Navigator} from 'react-native-deprecated-custom-components';
import BackGround from './components/BackGround';
import Login from "./components/Login";
import CreateAccount from "./components/CreateAccount";
export default class App extends Component {
render() {
return(
<View style={styles.back}>
<BackGround/>
<Navigator
initialRoute={{id: 'Login'}}
renderScene={this.navigatorRenderScene}
/>
</View>
);
}
navigatorRenderScene() {
_navigator = _navigator;
switch(route.id) {
case 'Login':
return (<Login navigator={navigator} title="Login"/>);
case 'CreateAccount':
return (<CreateAccount navigator={navigator} title="Create Account" />);
}
}
}
const styles = StyleSheet.create({
back: {
flex: 1
}
});
Here's BackGround.js:
import React, {Component} from 'react';
import {StyleSheet, Image, View, Text} from 'react-native';
import Login from './Login';
class BackGround extends Component {
render() {
return(
<View style={styles.first}>
<Image style={styles.container} source={require('../pictures/smoke.jpg')}>
<View style={styles.second}>
<View style={styles.movementTitle}>
<Text style={styles.title}>Dendro</Text>
</View>
<Login/>
</View>
</Image>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
width: null,
height: null,
backgroundColor: 'rgba(0,0,0,0)'
},
first: {
flex: 1
},
second: {
paddingTop: 290 // Moves both <TextInput> boxes down.
},
title: {
fontSize: 34,
textAlign: 'center',
justifyContent: 'center',
flexDirection: 'row',
fontFamily: 'Bodoni 72'
}
// movementTitle: {
// paddingBottom: 34
// }
});
export default BackGround;
Here's CreateAccount.js:
import React, {Component} from 'react';
import {Text} from 'react-native';
class CreateAccount extends Component {
render() {
return(
<Text>Must get to this page</Text>
);
}
}
export default CreateAccount;
Here's Login.js:
import React, {Component} from 'react';
import {StyleSheet, TextInput, Text, TouchableOpacity, KeyboardAvoidingView} from 'react-native';
class Login extends Component {
onButtonPress() {
this.props.navigator.push({
id: 'Create Account'
});
}
render() {
return(
<KeyboardAvoidingView behavior={"padding"} style={styles.container}>
<TextInput
style={styles.input}
returnKeyType={"next"}
keyboardType={"email-address"}
autoCorrect={false}
placeholder={"Email"}
/>
<TextInput
style={styles.input}
returnKeyType={"go"}
placeholder={"Password"}
secureTextEntry
/>
<TouchableOpacity>
<Text style={styles.loginAndCA}>Login</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.onButtonPress.bind(this)}>
<Text style={styles.loginAndCA}>Create Account</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
padding: 20 // Length of text input boxes.
},
input: {
backgroundColor: '#DAE5FF',
padding: 20,
paddingHorizontal: 15,
marginBottom: 10,
borderRadius: 15
},
loginAndCA: {
fontSize: 40,
textAlign: 'center',
color: 'white',
fontFamily: 'Bodoni 72 Smallcaps',
paddingHorizontal: 10
}
});
export default Login;
When you use standard React-Native you need to register your app with
AppRegistry.
If you create a new project react-native-init test and view the index.ios.js or index.android.js files, you will see the below code at the bottom of the file.
AppRegistry.registerComponent('test', () => test);

Categories

Resources