StackNavigation unable to find the screen? - react-native

While writing a demo stacknavigation app I am encountering an error on semulator stating
" Route 'Main' should declare a screen. For example:
import MyScreen from './MyScreen';
...
Main: {
screen: MyScreen,
}
C:\RN\blog\node_modules\react-navigation\src\routers\validateRouteConfigMap.js:23:8
validateRouteConfigMap
C:\RN\blog\node_modules\react-navigation\src\routers\validateRouteConfigMap.js:18:21
default
C:\RN\blog\node_modules\react-navigation\src\routers\StackRouter.js:47:25
default
C:\RN\blog\node_modules\react-navigation\src\navigators\StackNavigator.js:51:29
......
"
Why this is happening I don't know can anybody has any idea ?
The remain code are below
import React from 'react';
import { Text, View } from 'react-native';
import MainScreen from './MainScreen';
import RegisterScreen from './RegisterScreen';
import { StackNavigator } from 'react-navigation';
const ScreenList = StackNavigator({
Main: {
screen: MainScreen,
},
Register: {
screen: RegisterScreen,
},
});
export default ScreenList;
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import MainScreen from './src/screens/MainScreen';
import ScreenList from './src/screens/ScreenList';
export default class App extends Component<{}> {
render() {
return (
<View>
<ScreenList />
</View>
);
}
}
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { Card, Button, CardSection } from '../components/common/Index';
import Login from '../components/Login';
import ScreenList from './ScreenList';
export default class MainScreen extends Component {
render() {
return (
<View>
<Card>
<Login />
</Card>
<Text>----------------------------------</Text>
<Card>
<CardSection>
<Button>Register</Button>
</CardSection>
</Card>
</View>
);
}
}

Maybe its an issue with imports. Try removing
import MainScreen from './src/screens/MainScreen';
from App.js or wherever it is. It should work.

A guess, maybe you have not exported MainScreen Component.It will help if you can share the mainScreen file code.

Related

Error when using a Form : Element type is invalid expected a string but got undefined

I have the following error
Uncaught 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
I have read many post about this error, like this or this
but they all say the same : I incorrectly export my component. But I don't understand what is wrong with my export
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Image, ImageBackground, Linking, TouchableOpacity, TouchableHighlight, Alert, Button } from 'react-native';
import { createStackNavigator, createAppContainer } from "react-navigation";
import { FormLabel, FormInput, FormValidationMessage} from 'react-native-elements';
type Props = {};
export default class Login extends Component<Props> {
constructor(props) {
super(props);
state = {
login: '',
};
}
someFunction(){
Alert.alert("test")
}
onPress (){
this.props.navigation.navigate('Home')
}
checkLogin(login){
Alert.alert('test');
}
render() {
return (
<View style={styles.container}>
<Image
style={styles.image}
source={require("./images/logo.png")}>
</Image>
<FormLabel style={styles.flex1}>enter Login of your Hotel</FormLabel>
<FormInput
//value = {this.state.login}
onChangeText={login => this.checkLogin({login})}
//onChangeText={this.checkLogin.bind(login)}
placeholder='enter your login'
autoCapitalize = 'none'
/>
</View>
);
}
}
and App.js :
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Image,ImageBackground, Linking, TouchableOpacity, Alert } from 'react-native';
import { createStackNavigator, createAppContainer } from "react-navigation"
import {HomeScreen} from './HomeScreen';
import Display from './Display';
import Login from './Login';
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
const AppNavigator = createStackNavigator({
Home: HomeScreen,
Display: Display,
Login: Login,
},
{
initialRouteName: "Login",
headerMode: 'none',
}
);
const AppContainer = createAppContainer(AppNavigator);
Do you have an idea of what is wrong ? Error only comes when I use FormInput and FormLabel. If I replace by hello it is displayed
It seems that FormInput and FormLabel were deprecated in v1.0.0-beta.
See here (under v1.0.0-beta (beta 1) Changes section) - https://github.com/react-native-training/react-native-elements/releases/tag/v1.0.0-beta
You should use Input instead of FormInput with a label property instead of using FormLabel component.
<FormInput
label={"Login"} />

No content in TabNavigator

What could be the reason that content in Tab is not displayed?
I Receive a blank white box.
When I have only export const TopNavTabs without the class App it works but I need this as a component.
import React, { Component } from 'react'
import { Platform, View } from 'react-native'
import { TabNavigator } from 'react-navigation'
import General from './components/tabs/General'
import Help from './components/tabs/Help'
import Tips from './components/tabs/Tips'
export const TopNavTabs = TabNavigator({
General: { screen: General },
Help: { screen: Help },
Tips: { screen: Tips },
},
{
animationEnabled:true
});
export default class App extends Component{
render(){
return(
<View>
<TopNavTabs />
</View>
)
}
}
index.js
import React, {Component} from 'react';
import {AppRegistry, Text, View} from 'react-native';
import App from './src/App';
export default class Test extends Component {
render() {
return (
<App />
);
}
}
AppRegistry.registerComponent('test', () => Test);

React Native : StackNavigator Error : Invariant Violation : Element type is invalid

Getting this error (pictured below). New to react-native and learning how to use the StackNavigator. I believe it has something to due with export/imports but been stuck on this for a while. Thank you.
index.js file
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('RNIntroduction', () => App);
App.js file
import React, { Component } from 'react';
import {Platform, StyleSheet, Text, View, AppRegistry} from 'react-native';
import {StackNavigator} from 'react-navigation';
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
export default class App extends Component {
render() {
return (
<Screens/>
);
}
}
const Screens = StackNavigator({
LoginScreen: {screen: LoginScreen},
HomeScreen : {screen: HomeScreen}
})
LoginScreen.js
import React, { Component } from 'react';
import {Text, View, StyleSheet} from 'react-navigation';
export default class LoginScreen extends Component {
render() {
return (
<View>
<Text> This is Login Screen </Text>
</View>
);
}
}
My HomeScreen.js looks the same way as the LoginScreen.js. I also included a pic the error itself.
Change import statement LoginScreen.js to
import {Text, View, StyleSheet} from 'react-native';

React Native Base Toast error

I have the following React Native App set up and I'm trying to use the Toast component from Native Base:
app.js
import React, {Component} from 'react';
import {AppRegistry} from 'react-native';
import { Root } from "native-base";
import {StackNavigator} from 'react-navigation';
import MainView from './assets/screens/MainView';
import ConfigView from './assets/screens/ConfigView';
export default class myApp extends Component {
render() {
return (
<Root>
<AppNavigator />
</Root>
);
}
}
const Screens = StackNavigator({
Main: {screen: MainView},
Config: {screen: ConfigView}
})
AppRegistry.registerComponent('myApp', () => Screens);
MainView.js (simplified)
import React, {Component} from 'react';
import { StyleProvider, Card, CardItem, Left, Right, Body, Icon, Toast, Header, Fab } from 'native-base';
import {StackNavigator} from 'react-navigation';
export default class MainView extends Component {
....
showError = (msg, err) => {
console.log("[ERROR]", err);
Toast.show({
text: msg,
position: this.state.toastPosition,
buttonText: this.state.toastErrorBtn
});
}
....
}
I've tried several ways, but keep getting this error:
Your app should start with rendering myApp component, like this:
AppRegistry.registerComponent('myApp', () => myApp);.
Inside myApp you should render your app navigator which is Screens not AppNavigator, that is how you named it.
This is how your app.js should look:
import React, { Component } from 'react';
import { Root } from "native-base";
import { StackNavigator } from "react-navigation";
import MainView from './assets/screens/MainView';
import ConfigView from './assets/screens/ConfigView';
import {AppRegistry} from 'react-native';
export default class myApp extends Component {
render() {
return (
<Root>
<Screens />
</Root>
);
}
}
const Screens = StackNavigator({
Main: {screen: MainView},
Config: {screen: ConfigView}
})
AppRegistry.registerComponent('myApp', () => myApp);
We should use Root component
import { Root } from "native-base";
<Root>
// Screen
</Root>

Passing in action creators to react-navigation

I'm using the new react-navigation library for a React Native application I'm building. I'm having an issue with passing down my ActionCreators from my Nav component down to its scenes.
I have an AppContainer that wraps the entire application.
import React, { Component } from 'react';
import { DrawerNavigator, addNavigationHelpers } from 'react-navigation';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
import DashboardContainer from './DashboardContainer';
import CustomersContainer from './CustomersContainer';
const ApplicationNavigation = DrawerNavigator({
Dashboard: { screen: DashboardContainer },
Customers: { screen: CustomersContainer },
});
class AppContainer extends Component {
render() {
return (
<ApplicationNavigation />
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(() => { return {} }, mapDispatchToProps)(AppContainer);
Here is the CustomerContainer:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
export default class CustomerContainer extends Component {
btnPressed() {
this.props.listCustomers()
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
Now I'm trying to call an action within my CustomerContainer this.props.listCustomers(). The problem is the ActionCreator props aren't being passed down to the screens. I've tried doing adding the screenProps prop to the ApplicationNavigation component:
But for some reason when I do this my app doesn't display any screens its just blank with no errors.
UPDATE
So I updated my CustomerContainer file:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
console.log(this.props.listCompanyCustomers())
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
function mapStateToProps(state) {
return {
companyCustomers: state.companyCustomers
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(CustomerContainer);
This now works; however this feels like the incorrect way to go about this.
What redux connect basically does is:
Wrap your component
Declare contextProps to get access to dispatch
pass the dispatch to your component props.
If you pass the connect mapDispatchToProps, then it creates the mapping of the methods to dispatch.
So if you connect you AppContainer, its children won't get these dispatch methods, unless AppContainer passes them to its children (but this what connect comes to prevent).
So to sum up, you should connect any component that needs to use dispatch, otherwise it won't get it.
If you don't want to copy paste the mapDispatchToProps, you can just delete it and use this.props.dispatch instead:
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
this.props.dispatch(ActionCreators.listCompanyCustomers());
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}