Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The component for route must be a React component #3326

Closed
varunchandran333 opened this issue Jan 22, 2018 · 32 comments
Closed

The component for route must be a React component #3326

varunchandran333 opened this issue Jan 22, 2018 · 32 comments

Comments

@varunchandran333
Copy link

@varunchandran333 varunchandran333 commented Jan 22, 2018

This is the ERROR showing

The component for route 'Sign' must be a React component. For example:

import MyScreen from './MyScreen';
...
Sign: {
screen: MyScreen,
}

You can also use a navigator:

import MyNavigator from './MyNavigator';
...
Sign: {
screen: MyNavigator,
}


I was creating a Login page, where i need to switch to pages with Login and Signup.
I am including full code.Please guide me on this.

App.js

import React,{Component} from 'react';
import { AppRegistry, StyleSheet, Text, View,StatusBar} from 'react-native';

import { StackNavigator } from 'react-navigation';

import Login from './App/src/pages/Login';
import SignUp from './App/src/pages/SignUp';

export default class myapp extends Component{
render(){
return(




)
}

}

const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:'#455a64',
alignItems:'center',
justifyContent:'center'
}
});

AppRegistry.registerComponent('myapp', () => myapp);


Login.js

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, StatusBar } from 'react-native';

import { StackNavigator } from 'react-navigation';
import SignUp from '../pages/SignUp';

import Logo from '../component/Logo';
import Form from '../component/Form';
class Login extends Component {

static navigationOptions = {
    title: 'Login',
};

openSignup() {
    this.props.navigation.navigate('Sign');
}

render() {
    return (
        <View style={styles.container}>
            <Logo />
            <Form type='Login' />
            <View style={styles.signUpTextView}>
                <Text style={styles.signUpText}>
                    Don't Have an Account Yet?
            </Text>
                <Text style={styles.signUpButton} onPress={this.openSignup.bind(this)}>
                    SignUp
            </Text>
            </View>
        </View>
    )
}

}

export default Project1 = StackNavigator(
{
Sign: { screen: SignUp },

    Log: { screen: Login },
});

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#455a64',
alignItems: 'center',
justifyContent: 'center'
},
signUpTextView: {
flexGrow: 1,
alignItems: 'flex-end',
justifyContent: 'center',
paddingVertical: 16,
flexDirection: 'row',
},
signUpText: {
color: 'rgba(255,255,255,0.7)',
fontSize: 16
},
signUpButton: {
color: '#ffffff',
fontSize: 16,
fontWeight: '500',

},

});

SignUp.js

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, StatusBar } from 'react-native';

import { StackNavigator } from 'react-navigation';

import Login from '../pages/Login';

import Logo from '../component/Logo';
import Form from '../component/Form';
class SignUp extends Component {

static navigationOptions = {
    title: 'SignUp',
};

openLogin() {
    this.props.navigation.navigate('Log');
}

render() {
    return (
        <View style={styles.container}>
            <Logo />
            <Form type='SignUp' />
            <View style={styles.signUpTextView}>
                <Text style={styles.signUpText}>
                    Already have an Account?
            </Text>
                <Text style={styles.signUpButton} onPress={this.openLogin.bind(this)}>
                    Login
            </Text>
            </View>
        </View>
    )
}

}

export default Project2 = StackNavigator(
{
Sign: { screen: SignUp },

    Log: { screen: Login },
});

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#455a64',
alignItems: 'center',
justifyContent: 'center'
},
signUpTextView: {
flexGrow: 1,
alignItems: 'flex-end',
justifyContent: 'center',
paddingVertical: 16,
flexDirection: 'row',
},
signUpText: {
color: 'rgba(255,255,255,0.7)',
fontSize: 16
},
signUpButton: {
color: '#ffffff',
fontSize: 16,
fontWeight: '500',

},

});


I didnt find the issue.please guide me on this.
I dont know how

export default Project1 = StackNavigator(
{
Sign: { screen: SignUp },

    Log: { screen: Login },
});

this is implemented.
Where to add.

@kelset
Copy link

@kelset kelset commented Jan 22, 2018

Closing because you haven't followed the issue template; please open a new one that follows the template.
Without that, it's nearly impossible to understand & investigate the issue. I suggest you also try (in the new issue) to answer/explain in a way that fits these questions:

  1. have you tried updating to the latest release?
  2. does it happen only on Android/iOS?
  3. does it happen on both Debug and Release modes?
  4. does it happen with Debugger On or Off? Both?
  5. Can you provide a GIF or a repo or a snack to reproduce this issue?

@kelset kelset closed this Jan 22, 2018
@varunchandran333
Copy link
Author

@varunchandran333 varunchandran333 commented Jan 23, 2018

Closing because you haven't followed the issue template??? How to do that??
I started as a new issue? not an old one???

@varunchandran333
Copy link
Author

@varunchandran333 varunchandran333 commented Jan 23, 2018

have you tried updating to the latest release? i am working with latest
does it happen only on Android/iOS? i tested in android only
does it happen on both Debug and Release modes? i am a starter and just started. not a professional experienced developer. just learning

does it happen with Debugger On or Off? Both? i dont know

Can you provide a GIF or a repo or a snack to reproduce this issue? i have copy pasted the total code. in the issue . my 3 pages.

@varunchandran333
Copy link
Author

@varunchandran333 varunchandran333 commented Jan 23, 2018

I got the answer. I have just removed 1 and 3 line from index.js .
import { AppRegistry } from 'react-native'; //these lines
import App from './App';
AppRegistry.registerComponent('myapp', () => App); //these lines

@MutableLoss
Copy link

@MutableLoss MutableLoss commented Mar 23, 2018

Just for the sake of providing an answer, this will happen when the imported Component has not been properly exported. Looking at the above code, it looks like SignUp is lacking an export.

@mxdi9i7
Copy link

@mxdi9i7 mxdi9i7 commented May 27, 2018

I had the same issue and I've discovered that if I create the stack navigator in the same file as the component the error always pops up, I'd need to write my stack navigators from a different file for it to recognize the component as a real react component.
not sure if this is a bug...

@Shazam14
Copy link

@Shazam14 Shazam14 commented May 29, 2018

This is also my issue now, I can't seem to find that index.js!

@xanderberkein
Copy link

@xanderberkein xanderberkein commented Jun 12, 2018

I had this issue when I didn't export my ChildNavigator (located in another file) as default. I had multiple Navigators in that one file, so I exported these Navigators as named exports.

Changing export { ChildNavigator } to export default ChildNavigator fixed my problem.

@sbsanchez21
Copy link

@sbsanchez21 sbsanchez21 commented Jul 18, 2018

Gracias 3DEsprit, me funcióno cambiando el export a export default.

@samirph
Copy link

@samirph samirph commented Jul 30, 2018

Glad an answer was provided.

The docs just seem to show all the classes in a single file, didn't see any official example splitting screens in different files, not even splitting screen components.

That happens in the docs of many other frameworks, they show the code but you have no clue where it should be put in.

@yugandhar-pathi
Copy link

@yugandhar-pathi yugandhar-pathi commented Aug 22, 2018

This is a peculiar problem!!
I had an default export as follows in one of my class ..

export default class Login extends Component {
 ...
}

//It gave me this error ..
//And the error is resolved when ...

class Login extends Component {
 ...
}
export default Login;

Can someone tell me why ?

@alexpchin
Copy link

@alexpchin alexpchin commented Sep 2, 2018

@yugandhar-pathi Getting this as well...

@ZackLeonardo
Copy link

@ZackLeonardo ZackLeonardo commented Sep 29, 2018

in the validateRouteConfigMap.js:

if (
      !screenComponent ||
      (typeof screenComponent !== 'function' &&
        typeof screenComponent !== 'string' &&
        !routeConfig.getScreen)
    ) {
      throw new Error(`The component for route '${routeName}' must be a React component....

so:
you could try this:
() => <YOUR COMPONENT/>

such as:

export default createSwitchNavigator(  
  {  
    AuthLoading: () => <YOUR COMPONENT/>,  
    App: () => <YOUR COMPONENT/>,  
    Auth: () => <YOUR COMPONENT/>,  
  },  
  {  
    initialRouteName: 'AuthLoading',  
  }  
);

@sudarshanc
Copy link

@sudarshanc sudarshanc commented Oct 31, 2018

const MyNavigator = createStackNavigator(
  {
    RouteNameOne: {
      screen:() => <HomeScreen/>
    },
    RouteNameTwo: {
      screen:() => <NewScreen/>
    },
  },
  {
  initialRouteName: 'RouteNameOne',
  }
);

This worked for me.

@tarunmehta-quovantis
Copy link

@tarunmehta-quovantis tarunmehta-quovantis commented Nov 13, 2018

in my case I was exporting child(Composite) component as export default ChildComponent,
when I removed default. it worked .
might it help someone

@dominik-mrugalski
Copy link

@dominik-mrugalski dominik-mrugalski commented Dec 8, 2018

I found another solution:
My import code was:
import {WelcomeScreen} from './screens/WelcomeScreen'
and I had to change it to:
import WelcomeScreen from './screens/WelcomeScreen'

WelcomeScreen looks like:
import React, {Component} from 'react'; class WelcomeScreen extends Component { render() { [...] } }
After that my errors dissapeared :)

@rogerkerse
Copy link

@rogerkerse rogerkerse commented Dec 16, 2018

This problem also happens when you have circular dependencies. I for example had helper function in router file and scene imported it. When I moved this function to a seperate helper class, everything started working

@nandorojo
Copy link

@nandorojo nandorojo commented Jan 5, 2019

const MyNavigator = createStackNavigator(
  {
    RouteNameOne: {
      screen:() => <HomeScreen/>
    },
    RouteNameTwo: {
      screen:() => <NewScreen/>
    },
  },
  {
  initialRouteName: 'RouteNameOne',
  }
);

This worked for me.

This worked for me as well. Not sure where the problem for me – I suspect it is because I was using Redux's connect HOC.

@AnthonyLedesma
Copy link

@AnthonyLedesma AnthonyLedesma commented Jan 9, 2019

Had the same issues. Was able to resolve by importing my Navigator from separate file.

App.js

//...
import AppContainer from './navigator/MyNavigator';
//...
export default class App extends React.Component {
  render() {
    return <AppContainer />
  }
}

myNavigator.js

import  AuthScreen  from '../screens/Auth';
import  HomeScreen  from '../screens/Home';
import { createStackNavigator, createAppContainer } from "react-navigation";

const AppNavigator = createStackNavigator(
  {
    Home: HomeScreen,
    Auth: AuthScreen
  },
  {
    initialRouteName: "Home"
  }
);
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;

Using default exports on all files.

@faawaz1
Copy link

@faawaz1 faawaz1 commented Jan 18, 2019

Had the same issues. Was able to resolve by importing my Navigator from separate file.

App.js

//...
import AppContainer from './navigator/MyNavigator';
//...
export default class App extends React.Component {
  render() {
    return <AppContainer />
  }
}

myNavigator.js

import  AuthScreen  from '../screens/Auth';
import  HomeScreen  from '../screens/Home';
import { createStackNavigator, createAppContainer } from "react-navigation";

const AppNavigator = createStackNavigator(
  {
    Home: HomeScreen,
    Auth: AuthScreen
  },
  {
    initialRouteName: "Home"
  }
);
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;

Using default exports on all files.

Thank you , it's working with me

@besil
Copy link

@besil besil commented Jan 23, 2019

I had this issue when I didn't export my ChildNavigator (located in another file) as default. I had multiple Navigators in that one file, so I exported these Navigators as named exports.

Changing export { ChildNavigator } to export default ChildNavigator fixed my problem.

This worked for me, without removing nothing from index.js.
Very strange, thank you for this comment

@dihan
Copy link

@dihan dihan commented Jul 10, 2019

@krizpoon
Copy link

@krizpoon krizpoon commented Sep 2, 2019

I had the same problem. But since there are a lot of screens to convert from Objects to functions, I ended up writing a wrapper for this:

const wrapComponent = Comp => {
    return (props) => <Comp { ...props }/>;
};

const MyStackNavigator = (routeConfig, stackConfig) => {

    const newRouteConfig = {};
    const keys = Object.keys(routeConfig);
    for (let key of keys) {
        const route = routeConfig[key];
        if (typeof route.screen !== 'function') {
            newRouteConfig[key] = { ...route, screen: wrapComponent(route.screen) };
        }
        else {
            newRouteConfig[key] = route;
        }
    }

    return StackNavigator(newRouteConfig, stackConfig);
};

@kesepara
Copy link

@kesepara kesepara commented Oct 11, 2019

For those of you who is trying to write createBottomTabNavigator with [ ] array symbol, don't do it. It is the reason for you to get that error!

@briangonzalez
Copy link

@briangonzalez briangonzalez commented Oct 22, 2019

@kesepara Can you explain? Maybe show some example code?

@junocs
Copy link

@junocs junocs commented Nov 7, 2019

This problem also happens when you have circular dependencies. I for example had helper function in router file and scene imported it. When I moved this function to a seperate helper class, everything started working

This solves my problem

@MichaelRSilva
Copy link

@MichaelRSilva MichaelRSilva commented Dec 22, 2019

const MyNavigator = createStackNavigator(
  {
    RouteNameOne: {
      screen:() => <HomeScreen/>
    },
    RouteNameTwo: {
      screen:() => <NewScreen/>
    },
  },
  {
  initialRouteName: 'RouteNameOne',
  }
);

This worked for me.

This way, the 'navigation' attribute is not automatically entered on the first screen. Do you know how to add it?

Example: If my first screen is Splash, inside the constructor, props.navigation is undefined.

@AmitPandya007
Copy link

@AmitPandya007 AmitPandya007 commented Dec 29, 2019

While using the import for my screen I had mistakenly used it like below:
import {HomeScreen} from '../src/screens/HomeScreen';

which needs to be like:
import HomeScreen from '../src/screens/HomeScreen';

this resolved my error.

@gurudewan
Copy link

@gurudewan gurudewan commented Feb 11, 2020

Just make sure you declare the thing/stack/screen/component you're referring to before you refer to it and this works.

(This is why some people above said that importing it from a different file fixed their issue - imports are always at the top of the file)

@yilmazt81
Copy link

@yilmazt81 yilmazt81 commented Apr 21, 2020

Use like this .. fucking react i spend hours

const AutoStack = createBottomTabNavigator(
{
SignUp :SignUpScreen,
SignIn: SignInScreen
},
{
initialRouteName:'SignUp'
}
);

@pankajkmr036
Copy link

@pankajkmr036 pankajkmr036 commented Aug 13, 2021

I faced this issue while using latest version of react-redux (v7.x.x) with a very old version of react-navigation (v1.x.x).
The primary issue is that react redux connect HOC returns an object rather a function wheres older navigation/routing libraries of react and react-native expect their screens.routes to be React components.

Release notes of react-redux 7.0.1 ( (https://github.com/reduxjs/react-redux/releases/tag/v7.0.1)) states as follows:

Note: connect now uses React.memo() internally, which returns a special object rather than a function. Any code that assumed React components are only functions is wrong, and has been wrong since the release of React 16.6. If you were using PropTypes to check for valid component types, you should change from PropTypes.func to PropTypes.elementType instead.

To overcome this followed these steps

const ConnectDashboard = connect(
  mapStateToProps,
  mapDispatchToProps
)(Dashboard);

export default class DashboardScreen extends Component {
  render() {
    return <ConnectDashboard {...this.props} />;
  }
}
  1. Passing my React component to HOC connect
  2. Wrapping this returned object in another React component to keep it compatible with my navigation library.
  3. Using this wrapper component as my navigation screen.

@github-actions
Copy link

@github-actions github-actions bot commented Aug 13, 2021

Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet