Unable to resolve module from 'index.js' for custom component - reactjs

I'm kinda new to react-native and I'm currently trying to add a stack-navigator to my app:
// import React from 'react';
import {Text, View, AppRegistry} from 'react-native';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
// class HomeScreen extends React.Component {
// static navigationOptions = {
// title: 'Welcome',
// };
// render() {
// return (
// <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
// <Text>Home Screen</Text>
// </View>
// );
// }
// }
const MainNavigator = createStackNavigator({
Home: {screen: HomeScreen}
}, {
initialRouteName: 'Home'
})
const NavigationApp = createAppContainer(MainNavigator);
AppRegistry.registerComponent('ReactNativeApp', () => NavigationApp)
export default NavigationApp
If I uncomment the commented code in the above example, everything works fine, now I'm trying to move the HomeScreen component to its own file so I tried this:
HomeScreen.js
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
index.js
import HomeScreen from './components'
import {AppRegistry} from 'react-native';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
const MainNavigator = createStackNavigator({
Home: {screen: HomeScreen}
}, {
initialRouteName: 'Home'
})
const NavigationApp = createAppContainer(MainNavigator);
AppRegistry.registerComponent('ReactNativeApp', () => NavigationApp)
export default NavigationApp
But I keep getting this error:
error: bundling failed: Error: Unable to resolve module `./components` from `index.js`:
None of these files exist:
* components(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
* components/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
at ModuleResolver.resolveDependency (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:163:15)
at ResolutionRequest.resolveDependency (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:52:18)
at DependencyGraph.resolveDependency (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/node-haste/DependencyGraph.js:282:16)
at Object.resolve (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/lib/transformHelpers.js:267:42)
at /Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:426:31
at Array.map (<anonymous>)
at resolveDependencies (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:423:18)
at /Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:275:33
at Generator.next (<anonymous>)
at asyncGeneratorStep (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:87:24)
In the past I've been able to import them the same way as I did, but somehow react-navigation is giving me problems with it.
The folder structure that I have is as follows:
/
index.js
components/
HomeScreen.js
I have seen similar questions but all of them involved third-party components from react but not ones made by oneself.
I have tried to npm start --reset-cache as suggested in this answer
I'm using these versions if it matters.
react-native-cli: 2.0.1
react-native: 0.61.2
How to fix this error?
After following #Vencovsky proposed solution (with and without .js extension):
import HomeScreen from './components/HomeScreen.js'
I get this new 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,
}
The way I'm calling this React app is through a Swift bridge in this way:
import Foundation
import UIKit
import React
class ButtonController: UIViewController {
#IBOutlet weak var button: UIButton!
#IBAction func buttonClicked(_ sender: Any) {
if let jsBundleLocation = URL(string: "http://X.X.X.X:8081/index.bundle?platform=ios") {
//The data is used as initialProperties to React Native App.
let data:NSDictionary = ["onNavigationStateChange": "{handleNavigationChange}",
"uriPrefix":"/app"]; //We can use this parameter to pass the data to the React native App from the Native App.
//The RCTRootView is a native view used to host React-managed views within the app. Can be used just like any ordinary UIView.
let rootView = RCTRootView(
bundleURL: jsBundleLocation,
moduleName: "ReactNativeApp",
initialProperties: data as [NSObject : AnyObject],
launchOptions: nil)
let viewController = UIViewController()
viewController.view = rootView
self.present(viewController, animated: true, completion: nil)
}
}
}

You need to import it as
import HomeScreen from './components/HomeScreen.js'
If you only import it as './components', it will try to get ./components.js or ./components/index.js (and the same but with other extensions), but you don't have any of that.
And if you take a look at the error, it says it tried to get these files but didn't find.
None of these files exist:
* components(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
* components/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
First line with * - Trying to get ./components.js and other extensions
Second line with * - Trying to get ./components/index.js and other extensions

I solved the second issue after #Vencovsky answer by changing:
export class HomeScreen extends React.Component
To:
export default class HomeScreen extends React.Component
After reading this answer / comment on GitHub.

Related

Problems connecting api to react-native

i was doing a new app with react native i'm using rails/graphql but the problem is when i try to call the api url in my app with the configuration that i've made. it doesnt work at all (lauching expo cli), the error that o get is:
[Error: Network error: Network request failed]
i've already set the ip address of my pc instead of 'localhost' but i dont get any results my code is:
// React
import React from 'react';
// React-native
import { StyleSheet, Text, View } from 'react-native';
// Components
import Test from './app/components/Test/index';
import { ApolloProvider } from 'react-apollo'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context';
// 2
const httpLink = createHttpLink({
uri: 'http://my-ip-address:3000/graphql'
})
// 3
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
})
export default class App extends React.Component {
render() {
console.log('client ', client)
return (
<ApolloProvider client={client}>
<Test />
</ApolloProvider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
the component that is calling the query is:
// React
import React, { Fragment } from 'react';
// React-native
import { StyleSheet, Text, View } from 'react-native';
// React Apollo
import { graphql } from 'react-apollo';
import {flowRight as compose} from 'lodash';
// Queries
import queries from './queries';
class Test extends React.Component {
constructor() {
super();
}
render() {
console.log('props ', this.props);
return(
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>
Se conecto! 🎉
</Text>
</View>
);
}
}
export default compose(
graphql(queries.getSpots, { name: 'getSpots' }),
)(Test);
everything with the configuration was fine, the only thing that was happening was the way to start the rails server with my current version of rails. so instead of start off rails server with "rails s" i had to use "rails -b 0.0.0.0". after that i could connect my app from android emulator to my localhost:3000/graphiql
I didn't read your code but I know problem:
go to infor.plist
add (or change key) to react native - ios allow your api url
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>Your-API-URL-ROOT-HERE</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true />
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true />
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>

The AppNavigator is not exporting the required page

My SplashScreen page is not being exported by the AppNavigator even though the variable is declared and read, on the SplashScreen page.
I have tried to use createDrawerNavigator but I get the same result. I have tried to reset the cache with:
rm -rf node_modules && npm install
npm start -- --reset-cache
I have tried to reInstall the createDrawerNavigator
The error is below:
Unable to resolve module `./navigation/AppNavigator` from
`/Users/jaseyacey/Desktop/beermeapp4/screens/Splash.Screen.js`:
The module `./navigation/AppNavigator` could not be found from
`/Users/jaseyacey/Desktop/beermeapp4/screens/Splash.Screen.js`.
Indeed, none of these files exist:
The SplashScreen code is below:
import React, {Component } from 'react';
import {Image, View } from 'react-native';
import { inject } from 'mobx-react';
import AppNavigator from './navigation/AppNavigator';
import { createDrawerNavigator } from 'react-navigation-drawer';
#inject("stores")
class SplashScreen extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
const {stores, navigation } = this.props;
setTimeout(() => {
navigation.navigate("Login")
}, config.store.SplashTime )
}
render() {
const { stores } = this.props
return (
<View style={{flex: 1}}>
<image style={{flex: 1, width: null, height: null}} source= {config.store.SplashImg}/>
</View>
)
}
}
export default AppNavigator;
You should add you Splash Screen into your App Navigator and there you will create an App Container with your navigation type (drawer navigation in this case) and export the App Navigator containing your splash Screen as your first screen of navigation.
I don't have a Splash Screen on my project yet, but you can see how I configured my App Navigation here: https://github.com/pahferreira/destetik-mobile/blob/master/src/navigation/AppNavigation.js
Or you can check here on their documentation: https://reactnavigation.org/docs/en/hello-react-navigation.html

React navgiation AppRegistry is not registered

I have setup a brand new project using react-native init <proj> and it builds fine. I have added react-navigation to the project following the docs. However, I cannot get passed this error:
Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication)
Even using the single file stack example from their documentation:
import React from 'react';
import { View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
},
});
export default createAppContainer(AppNavigator);
It does not work. I am at a loss to what the issue could be here as I am using a base install with their working example and nothing else added. I have tried everything from restarting the bundler to clearing all caches I can think of.
Make sure you're registering the component:
const App = createAppContainer(navigator):
AppRegistry.registerComponent(appName, () => App)

module appregistry is not a registered callable module (calling runApplication)

i cannot find a way to make react-navigation work at all. i copied the working examples from the internet but they don't seem to work too. can someone tell me what i am doing wrong.
i'm using
node: 8.9.4
react: 16.3.0-alpha.1
react-native: 0.54.0
react-navigation: ^1.4.0
//index.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import {
TabNavigator,
StackNavigator
} from 'react-navigation';
import Home from './first';
import Homes from './second';
export default class demoApp extends Component {
render() {
return (
<SimpleNavigation/>
);
}
}
export const SimpleNavigation = StackNavigator({
Home: {
screen: Home,
header: { visible: false },
navigationOptions: {
title: 'Home',
header: null
},
},
Homes: {
screen: Homes,
navigationOptions: {
title: 'second'
},
},
},{});
Here's the first tab
//first.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TextInput,
Button,
TouchableHighlight
} from 'react-native';
export default class Home extends Component {
constructor(props){
super(props);
this.state = {zipCode: ''}
}
navigate = (zipCode) => {
this.props.navigation.navigate('Search', zipCode);
}
render() {
return (
<View>
<View>
<Text>An application to do things</Text>
<TextInput
placeholder='Enter a Zip Code'
onChangeText={(zipCode) => this.setState({zipCode})}
>
</TextInput>
</View>
<View>
<TouchableHighlight onPress={() => this.navigate(this.state.zipCode)}>
<Text>
Search
</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
i cant seem to make it run at all. I tried following many other tutorials as well. But none of them worked. What am i doing wrong?
I kept getting this error too today, and it was very annoying. Was able to get rid of it by removing the Terminal window with "Metro" bundler stuff, and then recompiling the app.
Seems like it's not the code, but rather the runtime environment (which seems to work well with only one app example at a time). You can double check this by doing a super simple app that should work.
Close your Nodejs Terminal and run again
Just kill all node process and start npm server and run application:
Step1: run command killall -9 node
Step2: run command npm start
Step3: run command react-native run-ios OR react-native run-android

referencing constants and variables across separate class files

My App.js file was getting very large, so I decided to move out all my classes to their own separate file, and this is what remains in my App.js
import React from 'react';
import {
AppRegistry,
Text,
View,
Button,
Image
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import { TabNavigator } from 'react-navigation';
//screen imports
import RecentChatScreen from './RecentChatScreen';
import AllContactsScreen from './AllContactsScreen';
import ChatScreen from './ChatScreen';
import HomeScreen from './HomeScreen';
import InfoScreen from './InfoScreen';
const MainScreenNavigator = TabNavigator({
Home: { screen: HomeScreen },
Recent: { screen: RecentChatsScreen },
All: { screen: AllContactsScreen },
});
const NavTest = StackNavigator({
Home: { screen: MainScreenNavigator },
Chat: { screen: ChatScreen },
Info: { screen: InfoScreen }
});
I think that looks fine.
However in some of the class files, I need to reference those other screens in button events, like this:
onPress={ () => navigate('Home')}
This worked fine before when everything was in App.js, but how would I reference these screens(Home, Chat, Info, Recent, All) now in the their separate files when the definitions are in App.js?
Thanks!
You can export them in App.js:
// App.js
// ...
export {
MainScreenNavigator,
NavTest,
}
And then import them from it:
import {MainScreenNavigator, NavTest} from './path/to/App.js';
If your intent is just to navigate to the different screens, and not use any properties defined within a particular screens class, then you would not need to import anything. When you define the StackNavigator and lets say you are passing in that value into the AppRegistry as the entry point of the application. In your case, it could be something like this:
AppRegistry.registerComponent('NavTest', () => NavTest)
Now within any of the screens, the navigatation object is passed in as a prop. You can then use that to navigate to any of the defined screens. The initial setup of the StackNavigator is essentially a mapping from a routeName to a react component (a class). So when you want to navigate to a particular class, all you need is the name of the route not the class or component it represents, the navigator already has all that. This name would be the key passed into the StackNavigator for a particular screen. In your example, the routeNames are Home, Chat and Info. So just doing something like this would work:
const { navigate } = this.props.navigation;
return (
<View>
<Text>Navigate Test</Text>
<Button onPress={() => navigate('Chat')} title="Go to chat"/>
</View>
);

Resources