I am working on the Expo basic chat app, and I need to use Stack Navigator, which I updated manually to 4.x. When I do that, however, it gives me the error message: (0 , _native.createStackNavigator) is not a function
This is app.js:
import Main from './components/Main';
import Chat from './components/Chat';
// Import React Navigation
import { createStackNavigator } from '#react-navigation/native'
// Create the navigator
const navigator = createStackNavigator({
Main: { screen: Main },
Chat: { screen: Chat },
});
// Export it as the root component
export default navigator
Here is main.js:
import React, { Component } from 'react';
import {
StyleSheet,
TextInput, // 1. <- Add this
View,
} from 'react-native';
class Main extends React.Component {
state = { name: '' } // 2. <- Add the component state
render() {
return (
<View>
<TextInput
style={styles.nameInput}
placeHolder="John Cena"
value={this.state.name}
/>
</View>
);
}
}
const offset = 24;
const styles = StyleSheet.create({
nameInput: { // 3. <- Add a style for the input
height: offset * 2,
margin: offset,
paddingHorizontal: offset,
borderColor: '#111111',
borderWidth: 1,
},
});
Any possible solutions?
Update to react navigation 5.x, the import { createStackNavigator } from '#react-navigation/native' is a syntax for 5.x, you are using 4.x
Related
Hi I am implementing react navigation in a react native app, and I am following the docs on react navigation. And I when I run the code this is the result:
My question is how do I make the center content's width same as the screen.
Also, his is my first time using react native expo after switching from reactJS
Code:
navigator code:
import Login from "./Login";
import Signup from "./Signup";
import {
createAppContainer,
NavigationContainer,
NavigationNavigator,
} from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import Chat from "./Chat";
import Error from "./Error";
/**
* This is the screen stack of the navigation stack.
*/
const screens: any = {
default: { screen: Login },
signup: { screen: Signup },
chat: { screen: Chat },
Error: { screen: Error },
};
const stack: NavigationNavigator<any, any> = createStackNavigator(screens);
const container: NavigationContainer = createAppContainer(stack);
export default container;
App.tsx:
import { StatusBar } from "expo-status-bar";
import React from "react";
import { Alert, StyleSheet, Text, View } from "react-native";
import * as expoAppLoading from "expo-app-loading";
import loadFonts from "./assets/fonts/loader";
import Navigator from "./screens/navigator";
/**
* This is the main app component of the Chill&chat application.
*/
const App: React.FC = () => {
const [loading, setLoading] = React.useState(true);
const style: any = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
text: {
fontFamily: "poppinsBold",
},
});
if (loading) {
return (
<expoAppLoading.default
startAsync={async (): Promise<void> => {
await loadFonts();
}}
onFinish={(): void => {
setLoading(false);
}}
onError={(): void => {
Alert.alert("Error", "Error loading fonts");
}}
/>
);
} else {
return (
<View style={style.container}>
<Navigator />
<StatusBar style="auto" />
</View>
);
}
};
export default App;
You should be able to set the width by adding percentage dimensions to your style sheet for the desired element. This may require you do away with flex layout however, or use flex in a parent instead.
container: {
width:'100%',
},
This should solve for the width problem though.
I just started learning React Native iOS recently and I am following raywenderlich tutorial
https://www.raywenderlich.com/485-react-native-tutorial-building-ios-apps-with-javascript#toc-anchor-001
I am using following versions:
react-native-cli: 2.0.1
react-native: 0.60.5
In the Adding Navigation Section, I am following the exact same steps but getting following errors
"you likely forgot to export your component from the file it's defined in and you might have mixed up with default and named imports"
Here is my App.js file code
'use strict';
import React, { Component } from 'react';
import { StyleSheet, Text, NavigatorIOS, View } from 'react-native';
class SearchPage extends Component<{}> {
render() {
return <Text style={styles.description}>Search for houses to buy!
</Text>;
}
}
class App extends Component<{}> {
render() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'Property Finder',
component: SearchPage,
}}/>
);
}
}
const styles = StyleSheet.create({
description: {
fontSize: 18,
textAlign: 'center',
color: '#656565',
marginTop: 65,
},
container: {
flex: 1,
},
});
export default App;
Index.js file code:
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
Please tell me what am I doing wrong? Thanks in advance!!!!
Try t ocheck import for registerComponent
import { AppRegistry } from 'react-native';
import App from './App'; // <--- check here
AppRegistry.registerComponent('PropertyFinder', () => App);
In my React-native project in the HomeScreen, I get some values from AsyncStorage. After getting this value I compare it and take decision in which screen it will go next.
If the getValue is null then it will go the WelcomeScreen and if it is not null then it will go the HomeDrawer Screen.
Here I have provided the code-
import React from 'react';
import { StyleSheet, Text, View, AsyncStorage } from 'react-native';
import {StackNavigator} from 'react-navigation';
import WelcomeScreen from './WelcomeScreen';
import LoginScreen from './components/LoginScreen';
import NoteMeHome from './components/NoteMeHome';
import HomeDrawer from './HomeDrawer/HomeDrawer';
import SettingsScreen from './components/SettingsScreen';
class HomeScreen extends React.Component {
state = {
getValue: '',
}
async componentDidMount() {
const token = await AsyncStorage.getItem('toke');
this.setState({ getValue: token });
}
render() {
console.log('#ZZZ:', this.state.getValue);
if(this.state.getValue !== null) {
return (
<AppStackNavigator/>
);
} else {
return (
<AppStackNavigator2/>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
const AppStackNavigator = new StackNavigator({
HomeDrawer: {screen:HomeDrawer},
WelcomeScreen: {screen:WelcomeScreen},
LoginScreen: {screen:LoginScreen},
NoteMeHome: {screen:NoteMeHome},
SettingsScreen: {screen:SettingsScreen}
})
const AppStackNavigator2 = new StackNavigator({
WelcomeScreen: {screen:WelcomeScreen},
HomeDrawer: {screen:HomeDrawer},
LoginScreen: {screen:LoginScreen},
NoteMeHome: {screen:NoteMeHome},
SettingsScreen: {screen:SettingsScreen}
})
export default HomeScreen;
Now, after running this, if I get null value in the variable getValue , then it is showing the following warning-
Warning: Can't call setState(or forceUpdate) on an unmounted
component. this is a no-op, but it indicates a memory leak in your
application. To fix, cancel all subscription and asynchronous tasks in
the componentWillUnmount method.
So, how can I solve this warning issue?
I don't know whether it's a good practice or not. The problem was- my component was initializing with empty string and I was checking for null in render function. Initializing getvalue with null or checking for empty string in render would solve this issue.
So, the change I made in my code is -
state = {
getValue: ''
}
And it removes the warning.
A better solution would be to use the SwitchNavigator from react-navigation since your navigation stacks are identical and you only want to route to the first screen based on that token.
see example
import React from 'react';
import { StyleSheet, Text, View, AsyncStorage } from 'react-native';
import {StackNavigator, createSwitchNavigator} from 'react-navigation';
import WelcomeScreen from './WelcomeScreen';
import LoginScreen from './components/LoginScreen';
import NoteMeHome from './components/NoteMeHome';
import HomeDrawer from './HomeDrawer/HomeDrawer';
import SettingsScreen from './components/SettingsScreen';
const AppStackNavigator = new StackNavigator({
HomeDrawer: {screen:HomeDrawer},
LoginScreen: {screen:LoginScreen},
NoteMeHome: {screen:NoteMeHome},
SettingsScreen: {screen:SettingsScreen}
});
export default createAppContainer(createSwitchNavigator(
{
LaunchScreen,
WelcomeScreen,
AppStackNavigator,
},
{
initialRouteName: 'LaunchScreen',
}
));
class LaunchScreen extends React.Component {
constructor(props) {
super(props);
this._getToken();
}
// Fetch the token from storage then navigate to the appropriate place
_getToken = async () => {
const tok = await AsyncStorage.getItem('toke');
// This will switch to the Welcome screen or main AppStack. Then this launch
// screen will be unmounted and thrown away.
this.props.navigation.navigate(tok ? 'AppStackNavigator' : 'WelcomeScreen');
};
// Render any loading content that you like here
render() {
return (
<View>
{/*...*/}
</View>
);
}
}
So I am learning React-Native and I have created a Drawer which has already worked before. But after a few modifications not involving the Drawer it keeps giving this error Can't find variable: Contact even if I am not importing a variable called Contact.
drawer.js
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { DrawerNavigator, DrawerItems } from 'react-navigation';
import ButtonScreen from '../screens/ButtonScreen';
import Contacts from '../screens/Contacts';
import Information from '../screens/Information';
import Preferences from '../screens/Preferences';
const Drawer = new DrawerNavigator({
Home: {
screen: ButtonScreen,
navigationOptions: {
drawerLabel: 'Button'
},
},
Contacts: {
screen: Contacts,
},
Preferences: {
screen: Preferences,
},
Info: {
screen: Information,
}
}, {
contentComponent: (props) => (
<View>
<Text>Custom Header</Text>
<DrawerItems {...props}/>
<Text>Custom Footer</Text>
</View>
)
});
export default Drawer;
Contacts.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View, Text } from 'react-native';
class Contacts extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Text>
Contact Component
</Text>
</View>
);
}
}
const mapStateToProps = (state) => {
const { isDrawerOpened } = state;
return { isDrawerOpened };
}
export default connect(mapStateToProps)(Contacts);
By the stacktrace the error is comming from drawer.js line 6, where I import Contacts and not Contact. I already runned npm start -- --reset-cache to see if it would solve it but no. I am very confuse about why this is happening.
My application contain drawer navigator and stack navigator. But issue is that when i tried to goback it takes me to first screen even if i am 2-3 stack deep. It don't show previous screen it always takes me to main screen. Below is my App.js code
import React from 'react';
import {
ActivityIndicator,
AsyncStorage,
Button,
StatusBar,
StyleSheet,
View,
} from 'react-native';
import {StackNavigator, SwitchNavigator, DrawerNavigator} from 'react-navigation';
import Screen1 from './Screen/Screen1';
import Screen2 from './Screen/Screen2';
import Screen3 from './Screen/Screen3';
import Screen4 from './Screen/Screen4';
import Screen5 from './Screen/Screen5';
import ScreenList from './Screen/ScreenList';
import Login from './Screen/Login';
class AuthLoadingScreen extends React.Component {
constructor() {
super();
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const userToken = await AsyncStorage.getItem('user');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<ActivityIndicator/>
<StatusBar barStyle="default"/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
const AppStack = DrawerNavigator({
Screen1: { screen: Screen1},
Screen2: { screen: Screen2},
Screen3: { screen: Screen3},
Screen4: { screen: Screen4},
Screen5: { screen: Screen5},
ScreenList: { screen: ScreenList},
}, {contentComponent: SideBar});
const AuthStack = StackNavigator({Login: { screen: Login}},{headerMode:'none'});
const MyNavigator = SwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading'
}
);
export default class App extends React.Component {
render() {
return <MyNavigator />;
}
}
From Screen 1, i click on button and go to screen 2 and screen 3 like:
onPress={() => navigate('Screen2', { })}
And it works fine, but when i go back using bellow code from screen 3 it takes me to screen 1 not screen 2
this.props.navigation.goBack();
Am i missing something?
Did you try
1 -> 2 -> 3 -> 4
<Button
onPress={() => goBack('3')}
title="Go to 3 screen"
/>