Undefined navigator.push React-native 0.43.4 - reactjs

I am using the Navigator component of react-native but i still get error when i want to push to anthor page push undefined is not a function so there is my code
import React, { Component } from 'react';
import {
View,
StyleSheet,
Navigator,
Text,
TouchableHighlight
} from 'react-native';
import Home from './Home';
import Main from './Main';
class MainApp extends Component {
_navigate(){
this.props.navigator.push({
name: Home
})
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={ () => this._navigate() }>
<Text>GO To View</Text>
</TouchableHighlight>
</View>
);
}
}
and Home component
class Home extends Component {
render() {
return (
<View style={styles.container}>
<Text>Welcome Hello</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default Home;
I still get this error, I am a beginner in react-native so help me please ? why react-native so hard ?

After some hours of work, i resolve my problem
First i create MainApp and i define a Navigator with initialRoute my code look like this
class MainApp extends Component {
renderScene(route, navigator) {
console.log(route, navigator);
if (route.component) {
return React.createElement(route.component, { navigator });
}
}
render() {
return (
<Navigator
initialRoute={{name: 'Home', component: Home}}
configureScene={() => {
return Navigator.SceneConfigs.FloatFromRight;
}}
renderScene={this.renderScene}
/>
);
}
}
and after in Home screen i use this function
_navigate() {
this.props.navigator.replace({
name: 'Main',
component: Main
});
}
So now my project work well , the key is create a screen route hope it useful

So ! First of all, RN is not so hard ^^ I started two weeks ago don't worry it will become easier !
I'll give you an example if you're ok with that !
MainApp
renderScene(route,nav) {
switch (route.screen) {
case "LaunchScreen":
return <LaunchScreen navigator={nav} />
case "LoginScreen":
return <LoginScreen navigator={nav} />
case "ListBillScreen":
return <ListBillScreen navigator={nav} />
case "AddBillScreen":
return <AddBillScreen navigator={nav} />
case "BillScreen":
return <BillScreen navigator={nav} bill={route.props}/>
case "PersistanceDemo":
return <PersistanceDemo navigator={nav} />
}
}
render () {
return (
<Navigator
initialRoute={{screen: 'LaunchScreen'}}
renderScene={(route, nav) => {return this.renderScene(route, nav)}}
/>
)
}
}
You set all your "Routes" in the mainApp okay?
After that, if you want to navigate between views in others .js, you need to do this way :
this.props.navigator.push({ screen: 'AddBillScreen' });
You need to navigate with the name of your screen ! Once you've done that, it will be soooo easy for you to navigate between views you will see !
Keep strong !

Related

React Native - render a component onClick on an Icon

A part of my app has an 'icon'. When I 'click' on the icon, the State of the parent component changes to 'true' and I want a new 'Component' to render saying 'I am a new Component'. I am trying like this below, there is no error showing at the debugger. The Icon is an image component that I am importing. Here is the Code.
This is the parent Component
import React, {Component} from 'react';
import {View} from 'react-native';
import {Icon} from '../ui/Icon';
type HomeSceneState = {
calendarState:boolean
}
class HomeScene extends Component<HomeSceneState> {
state = {
calendarState:false
}
openCalendar = () => {
console.log("open calendar")
this.setState({
calendarState : true
})
}
render() {
return (
<View style={{marginBottom: spacing.double,
backgroundColor:"black", flexDirection:"row"
}}>
<View>
<Icon onPress = {() => this.openCalendar()} />
{this.calendarState ? <Casie/> : null }
</View>
</View>
);
}
}
export default HomeScene;
The Children Component looks like below
class Casie extends Component<CalendarProps> {
render() {
return (
<View>
I am a new Component
</View>
);
}
}
export default Casie;
replace <Calendar/> by your child component name <Casie/> (in your case). It seems you are not rendering your child component when the state changes.
In your parent component you import the react native navigation.
after you can use useNavigation for navigate the page. Sorry my english.
import { useNavigation } from '#react-navigation/native'
class HomeScene extends Component<HomeSceneState> {
state = {
calendarState:false
}
openCalendar = () => {
console.log("open calendar")
navigation.navigate('Casie')
}
render() {
return (...)
}
}
export default HomeScene;

Initialize react-native application with class components

I have just installed create-react-native-app and created one. I can see that app is a function there
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
</View>
);
}
I know that both Functional and Class-Components in available in React. Now I want to create app with Class Components. Can somebody suggest how to do it?
For people who come from heavy object-oriented background, the class-based component will let them jump on reactjs relatively quickly compared to a functional-based component.
Here is some basic skeleton of the class component:
import * as React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
export default class App extends React.PureComponent {
constructor() {
// Where you initialize some data
}
componentDidMount() {
// Lifecycle method when your component is mounted
}
componentWillUnmount() {
// Lifecycle method when your component is unmounted
}
_handleOnButtonPress = () => {
// Handler when your button is pressed
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._handleOnButtonPress}>
<Text>Open up App.tsx to start working on your app!</Text>
</TouchableOpacity>
</View>
);
}
}
And here is a further reference to compare class and functional component. Cheers!
Here is code for you :
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount = () => {
// initial method
};
render() {
return (
<View>
<Text>Test</Text>
</View>
);
}
}
const styles = StyleSheet.create({
});
export default App;
You don't need to make it a class unless you are using state in the class

this.props.navigation.navigate() doesn't work (using WithNavigation)

I have implemented a pop-up component in a header with More Options button. This button is available only on the UserProfileScreen. When you press on it you see two buttons: 'Settings' and 'Log out'. The issue is related to Settings button.
Expected behavior:
Press on Settings button -> this.props.navigation.navigate('SettingsNavigator') is called -> SettingsScreen is shown
Actual behavior:
Press on Settings button -> console.warn('go to settings') is called and nothing more (you are not redirected to SettingsScreen).
SettingsNavigator.js
import React from 'react';
import { createStackNavigator } from 'react-navigation';
import SettingsScreen from './SettingsScreen';
import EditProfileScreen from './EditProfileScreen';
import RemoveProfileScreen from './RemoveProfileScreen';
const SettingsNavigator = createStackNavigator({
SettingsScreen: SettingsScreen,
EditProfile: EditProfileScreen,
RemoveProfile: RemoveProfileScreen
}, {
initialRouteName: 'SettingsScreen'
});
export default SettingsNavigator;
optionHeaderButton.js
import { withNavigation } from 'react-navigation';
...
class OptionsHeaderButton extends Component {
...
navigateToSettings = () => {
console.warn('go to settings')
this.props.navigation.navigate('SettingsNavigator');
}
render() {
return(
<Menu onSelect = {value => {
switch(value) {
case 'Settings':
this.navigateToSettings();
break;
case 'Logout':
this.onLogOutPress();
break;
}
}}>
<MenuTrigger>
<Icon name = 'dots-vertical' size = {24} color = {text}/>
</MenuTrigger>
<MenuOptions style = {optionsHeaderButtonStyle.menuWrapper}>
<MenuOption value = {'Settings'}>
<View style = {optionsHeaderButtonStyle.optionWrapper}>
<View style = {optionsHeaderButtonStyle.optionIcon}>
<IconSimpleLine name = 'settings' size = {12} color = {text}/>
</View>
<Text style = {[optionsHeaderButtonStyle.option, optionsHeaderButtonStyle.lastOption]}>
Settings
</Text>
</View>
</MenuOption>
<MenuOption value = {'Logout'}>
<View style = {optionsHeaderButtonStyle.optionWrapper}>
<View style = {optionsHeaderButtonStyle.optionIcon}>
<IconSimpleLine name = 'logout' size = {12} color = {text}/>
</View>
<Text style = {[optionsHeaderButtonStyle.option, optionsHeaderButtonStyle.lastOption]}>
Logout
</Text>
</View>
</MenuOption>
</MenuOptions>
</Menu>
)
}
}
export default withNavigation(OptionsHeaderButton);
OptionsHeaderButton is nested to a Header Component that is nested in UserProfile Component.
As far as I know using withNavigation() I can call navigation.navigate() from any component. So why doesn't it work?
UPDATE:
After investigation I found that this issue is related to a bug of React Navigation that was found on April of 2017. It means that you can use navigation.navigate() only inside one Stack. But I can't find any info about fix of this bug.
you need to pass screen name instead of navigator.
this.props.navigation.navigate('SettingsSecreen');
try this:
import { NavigationActions, withNavigation } from 'react-navigation';
navigateToSettings = () => {
const navigateAction = NavigationActions.navigate({ routeName: 'SettingsScreen' });
this.props.navigation.dispatch(navigateAction);
}
I had this issue but I have wired up my App.js slightly differently using stack navigation and drawer navigation (And switch navigation for auth) - mostly followed the react navigation docs:
App.js
const AuthStack = createStackNavigator({ Login: Login }, { headerMode: 'none' });
const ActivityStack = createStackNavigator({ Activity: ActivityScreen}, {headerMode: 'none'});
// setup my routing & config here
export default createAppContainer(createSwitchNavigator(
{
Auth: AuthStack,
ActivityStack: ActivityStack,
},
{
intitalRouteName: 'Auth',
},
));
In the screen I want to navigate from I wire up the constructor like this (to bind the navigation function):
FirstScreen.js
export default class FirstScreen extends React.Component {
constructor(props) {
super(props);
this.navigateToScreen = this.navigateToScreen.bind(this);
}
state = {
// state items here
}
navigateToScreen(screenName) {
this.props.navigation.navigate(screenName);
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress=
{this.navigateToScreen("Activity")}>
<Text style={styles.loginText}>
ADD ACTIVITY
</Text>
</TouchableOpacity>
</View>
Note how I am calling the navigation, I am only passing in the route alias I gave earlier in the App.js file:
Activity: ActivityStack,
So I would write this.navigateToScreen("Activity") from the calling point passing in the alias not the screen name or stack name.
This navigates correctly to the screen and utilizes stack navigation I defined earlier in App.js.
Hope this makes sense (parent child hierarchy is achieved by nesting the various navigation features like switch, stack and drawer to achieve your desired results.
in react-navigation Version: 5.x withNavigation is not working. To fix this issue try this.
import { useNavigation } from '#react-navigation/native';
const navigation = useNavigation();
navigation.navigate("DetailsScreen")
no need to warp the component in withNavigation.
Hope this may helps.

Pass state data between component through navigator

my issue is look so simple but I can't figure is out how to solve it
I have two component that I navigate to them by using StackNavigator,
in one of the component I have state with values, I need to pass the state values to the other component, but as I said I using StackNavigator to go from one component to the other, I trying to figure out how can I do so
my navigator:
const Navigate = StackNavigator(
{
Home: { screen: HomeScreen },
Riddles: { screen: RiddlesScreen },
Introduction: { screen: IntroductionScreen },
About: { screen: AboutScreen },
},
{ headerMode: 'screen' }
);
My homescreen class:
class HomeScreen extends Component {
static navigationOptions = {
header: null
}
render() {
return (
<View>
<Home navigation={this.props.navigation} />
</View>
);
}
}
my riddlescreen class:
class RiddlesScreen extends Component {
static navigationOptions = {
header: null
}
render() {
return (
<View>
<Riddles navigation={this.props.navigation} />
</View>
);
}
}
in the Riddles component (at the RiddleScreen class) I have state with the values that I need to pass to Home component (at HomeScreen class).
what is the best way to achieve this goal?
every help really appreciated! thanks.
You can pass data between screens while navigating. More info here.
Example
<Button onPress={() => {this.props.navigation.navigate('SomeScreen', { some: this.state.someValue})}} />
// and in SomeScreen
console.log(this.props.navigation.state.params.some);

Navigate to completely different screen on React Native

On my React Native app I am initially loading SceneA, which simply displays a text "Click me". When this button is clicked I would like to load a completely different screen (SceneB) that has completely different components.
All the examples that I found online (like the example below) load a scene with exactly the same components, but different values. In my case it is a completely different layout. How can I navigate to that new screen (SceneB)?
It is basically the equivalent to a new Activity on Android, passing some data at the same time. Any pointers will be appreciated.
index.android.js
import React, { Component } from 'react';
import { AppRegistry, Navigator } from 'react-native';
import SceneA from './SceneA';
class ReactNativeTest extends Component {
render() {
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) =>
<SceneA
title={route.title}
// Function to call when a new scene should be displayed
loadNewScene={() => {
const nextIndex = route.index + 1;
navigator.push({
title: 'Scene B',
index: nextIndex,
});
}}
/>
}
/>
)
}
}
AppRegistry.registerComponent('ReactNativeTest', () => ReactNativeTest);
SceneA.js
import React, { Component, PropTypes } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class SceneA extends Component {
render() {
return (
<View>
<Text>Scene A</Text>
<TouchableHighlight onPress={this.props.loadNewScene}>
<Text>Click Me</Text>
</TouchableHighlight>
</View>
)
}
}
SceneA.propTypes = {
loadNewScene: PropTypes.func.isRequired,
};
You handle which components should render in the renderScene function, each scene will have a route.title so you can decide which to render based on that.
renderScene={(route, navigator) =>
if (route.title === 'Scene A') {
return <SceneA navigator={navigator} />
}
if (route.title === 'Scene B') {
return <SceneB navigator={navigator} />
}
}
Then inside your components you're gonna have a function that handles the navigation:
navigateToSceneB = () => {
this.props.navigator.push({
title: 'Scene B'
})
}

Resources