Disable console log in react navigation - react-native

I'm using react navigation for my app development. When i run log-android, it keeps logging something like this.
Navigation Dispatch: Action: {...}, New State: {...}
which is from createNavigationContainer.js line 150.
I've run through github and document said it could be done by by setting onNavigationStateChange={null} on a top-level navigator.
How can i achieve this by setting onNavigationStateChange={null} and where should i set it?
I've try to set like below, but it the page will not be able to redirect to other page.
export default () => {
<App onNavigationStateChange={null} />
}
Below are my app.js code
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
import { StackNavigator,DrawerNavigator } from 'react-navigation';
import DrawerContent from './components/drawer/drawerContent.js';
import News from './components/news/home.js';
const drawNavigation = DrawerNavigator(
{
Home : {
screen : News ,
navigationOptions : {
header : null
}
}
},
{
contentComponent: props => <DrawerContent {...props} />
}
)
const StackNavigation = StackNavigator({
Home : { screen : drawNavigation,
navigationOptions: {
header: null
}
}
});
export default StackNavigation;
This is my drawerContent.js
import React, {Component} from 'react'
import {View,Text, StyleSheet,
TouchableNativeFeedback,
TouchableOpacity,
TouchableHighlight
} from 'react-native'
import { DrawerItems, DrawerView } from 'react-navigation';
import Icon from 'react-native-vector-icons/Octicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
class DrawerContent extends Component {
constructor(props){
super(props);
console.log('DrawerContent|testtttttt');
}
render(){
return (
<View style={styles.container}>
<Text>Hi darren</Text>
<TouchableOpacity style={{ marginBottom:5 }} onPress={() => this.props.navigation.navigate('RegistrationScreen') } >
<View style={styles.nonIconButton}>
<Text style={{ color: 'black',fontSize: 13 }} >Sign Up</Text>
</View>
</TouchableOpacity>
<Text>Hi darren</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default DrawerContent;

First, make sure you are using the latest release of react-navigation as the comment noting that the fix was committed is fairly recent.
Based on your code example, to disable logging for all navigation state changes, you would want to replace this code:
export default StackNavigation;
with:
export default () => (
<StackNavigation onNavigationStateChange={null} />
);
as StackNavigation appears to be your root navigator.

React navigation is great, but this logging is really bad. Solution
const AppNavigator = StackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
render() {
return (
<AppNavigator onNavigationStateChange={null} />
);
}
}

Related

<TouchableOpacity onPress={() => navigation.navigate('Baslica')}> doesn't navigate any screen

I tried to give an onPress action to one of my custom button made with TouchableOpacity. It is supposed to navigate me to another screen. I did how exactly i did at other screens but this time it doesn't work and don't get any error as well. On the Navigation.js, when i give initialRouteName manually, screen appears, but when i click on the button, nothing happens.
Home Screen:
import React from "react";
import { StyleSheet, View, StatusBar, Image, ImageBackground, TouchableOpacity} from "react-native";
const HomeScreen = ({ navigation }) => {
return (
<View>
<TouchableOpacity onPress={() => navigation.navigate('Baslica')}>
<ImageBackground
source={require("../../assets/HomeScreen/baslicaButton.png")}
resizeMode="contain"
style={styles.baslicaButton}
imageStyle={styles.baslicaButton_imageStyle}
>
<Image
source={require("../../assets/HomeScreen/baslicaText.png")}
resizeMode="contain"
style={styles.baslicaText}
></Image>
</ImageBackground>
</TouchableOpacity>
</View>
);
}
export default HomeScreen;
Navigation JS:
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import IntroScreen from './src/screens/IntroScreen';
import HomeScreen from './src/screens/HomeScreen';
import BaslicaScreen from './src/screens/BaslicaScreen';
const navigator = createStackNavigator(
{
Intro: IntroScreen,
Home: HomeScreen,
Baslica: BaslicaScreen
},
{
initialRouteName: "Intro",
}
);
export default createAppContainer(navigator);
You need to wrap your components between AppContainer tags in your root component similar with below so that the navigation object become aware of the react-navigation context.
import AppContainer from './navigation'; // your navigation.js file
export default class RootApp extends React.Component {
...
render() {
return <AppContainer>
// the rest of your other components here
</AppContainer>
}
}
you Should use navigation param like this:
this.props.navigation.navigate("yourScreen", { ParamName: Valu });
Edit Your code like This:
import React from "react";
import { StyleSheet, View, StatusBar, Image, ImageBackground, TouchableOpacity} from "react-native";
const HomeScreen = ({ navigation }) => {
return (
<View>
<TouchableOpacity onPress={() =>
this.props.navigation.navigate('Baslica')}>
<ImageBackground
source={require("../../assets/HomeScreen/baslicaButton.png")}
resizeMode="contain"
style={styles.baslicaButton}
imageStyle={styles.baslicaButton_imageStyle}
>
<Image
source={require("../../assets/HomeScreen/baslicaText.png")}
resizeMode="contain"
style={styles.baslicaText}
></Image>
</ImageBackground>
</TouchableOpacity>
</View>
);
}
export default HomeScreen;
and Edit this code like that :
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import IntroScreen from './src/screens/IntroScreen';
import HomeScreen from './src/screens/HomeScreen';
import BaslicaScreen from './src/screens/BaslicaScreen';
const navigator = createStackNavigator(
{
Intro: {screen:IntroScreen},
Home: {screen:HomeScreen},
Baslica: {screen:BaslicaScreen},
},
{
initialRouteName: "Intro",
}
);
export default createAppContainer(navigator);

Undefined is not an object for react navigation

I have two components for my project, and I have gone through all the steps for react navigation as follow:
// App.js
import React from 'react';
import Main from './app/componenets/Main'
import details from './app/componenets/details'
import { createStackNavigator, createAppContainer } from 'react-navigation'
const mainNavigator = createStackNavigator(
{
MainScreen: Main,
detailsScreen: details,
},
{
initialRouteName :'MainScreen'
}
);
const AppContainer = createAppContainer(mainNavigator);
export default class App extends React.Component{
render() {
return(
<AppContainer />
);
}
}
Then I have my Main.js which I have a method as follow:
import React from 'react';
import {
StyleSheet ,
Text,
View,
} from 'react-native'
import Note from './Note'
import detail from './details'
import { createStackNavigator, createAppContainer } from "react-navigation";
export default class Main extends React.Component {
static navigationOptions = {
title: 'To do list',
headerStyle: {
backgroundColor: '#f4511e',
},
};
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: ''
}
}
render() {
let notes = this.state.noteArray.map((val,key) => {
return <Note key={key} keyval={key} val={val}
goToDetailPage= {() => this.goToNoteDetail(key)} />
});
const { navigation } = this.props;
return(
<View style={styles.container}>
<View style={styles.footer}>
<TextInput
onChangeText={(noteText) => this.setState({noteText})}
style={styles.textInput}
placeholder='What is your next Task?'
placeholderTextColor='white'
underlineColorAndroid = 'transparent'
>
</TextInput>
</View>
<TouchableOpacity onPress={this.addNote.bind(this)} style={styles.addButton}>
<Text style={styles.addButtonText}> + </Text>
</TouchableOpacity>
</View>
);
}
//This method is declared in my Note.js
goToNoteDetail=(key)=>{
this.props.navigation.navigate('detailsScreen')
}
}
//Styles which I didn't post to be short in code here
But when I try to do the navigation I get this error:
'undefined is not and object(evaluating 'this.props.val.date')
Do I need to pass the props in a way? or should I do anything else? I am new to React native and confused!
in order to access this.props make arrow function or bind the function in constructor.
goToDetail=()=>{
this.props.navigation.navigate('detailsScreen')
}
Just remove createAppContainer
const AppContainer = mainNavigator;
and tell me what react-navigation that you work with

Is there an easy way to create a logout button in the drawer in React Navigation V2?

I want to have logout button in my drawer. The problem is that it should not render a screen, but just straight up log out. Is there a easy way to do it (e.g. somehow modifying the contentOptions' items or onItemPressed property? I couldn't figure something out.
What I'm doing right now is writing a CustomDrawerComponent with a logout button in it, but it's pretty hard to get the styling right and look alike the other DrawerItems.
Here is how I solved this with a custom component. Maybe there is a different way?
import React, { PureComponent } from "react";
import { Image, ScrollView, Text, TouchableOpacity } from "react-native";
import { DrawerItems, SafeAreaView } from "react-navigation";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { clearToken } from "../../api/secureStorage/secureStorage";
import { BUTTON_TEXT_LOGOUT } from "../../config/constants/buttonTexts";
import { logout } from "../../redux/actions/logout/logout";
import styles from "./styles";
export class BurgerMenu extends PureComponent {
static propTypes = {
navigation: PropTypes.object,
logout: PropTypes.func.isRequired
};
logout = () => {
const { navigation, logout } = this.props;
clearToken().then(() => {
logout();
navigation.navigate("LoginScreen");
});
};
render() {
const { logout, ...strippedProps } = this.props; // eslint-disable-line no-unused-vars
return (
<SafeAreaView style={styles.container} forceInset={{ top: "always", horizontal: "never" }}>
<ScrollView>
<DrawerItems {...strippedProps} />
</ScrollView>
<TouchableOpacity style={[styles.footer, styles.item]} onPress={this.logout}>
<Image
source={require("../../assets/icons/exit.png")}
style={styles.icon}
resizeMode="contain"
/>
<Text style={styles.text}>{BUTTON_TEXT_LOGOUT}</Text>
</TouchableOpacity>
</SafeAreaView>
);
}
}
export default connect(
null,
{ logout }
)(BurgerMenu);

Cannot read property 'navigate' of Undefined in React Navigation

i'm React Native newbie. What i'm trying to do is added react navigation to my login page where user can click a button and navigate to the sign up page but i'm getting an error Cannot read property 'navigate' of Undefined. I've already searched the solution over an internet but no luck. This So does not help me - React Navigation - cannot read property 'navigate' of undefined and same with others .
Here is my code
index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import {StackNavigator} from 'react-navigation';
import Login from './src/screens/Login';
import Signup from './src/screens/Signup';
export default class tapak extends Component {
constructor(props) {
super(props);
this.buttonPress = this.buttonPress.bind(this);
}
render() {
return (
<View style={styles.container}>
<Text style={{color: 'blue'}} onPress={this.buttonPress}>sign up</Text>
</View>
);
}
buttonPress() {
console.log('called');
this.props.navigation.navigate('Signup');
}
}
const Stacks = StackNavigator({
Login: {
screen: Login
},
Signup:{
screen: Signup
}
});
Render the StackNavigator in your index.ios.js and move the button to the Login component:
const Stacks = StackNavigator({
Login: {
screen: Login
},
Signup:{
screen: Signup
}
});
class tapak extends Component {
render() {
return (
<Stacks />
);
}
}
Login.js :
export default class Login extends Component {
constructor(props) {
super(props);
this.buttonPress = this.buttonPress.bind(this);
}
buttonPress() {
console.log('called');
this.props.navigation.navigate('Signup');
}
render() {
return (
<View style={styles.container}>
<Text style={{color: 'blue'}} onPress={this.buttonPress}>sign up</Text>
</View>
);
}
}
Working example
here.
Write this code to index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import {StackNavigator} from 'react-navigation';
import Login from './src/screens/Login';
import Signup from './src/screens/Signup';
const Stacks = StackNavigator({
Login: {
screen: Login
},
Signup:{
screen: Signup
}
});
Login.js
import React ,{Component} from 'react';
import {
Text, View , Button,Image,
} from 'react-native';
export default class HomeScreen extends Component {
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text
onPress={() => navigate('Signup')}
> SignUp</Text>
</View>
);
}
}
Hope this help you.
I think you need to include navigationOptions, for example:
class MyComponent extends React.Component {
static navigationOptions = {
title: 'Great',
// other configurations
}
render() {
return (
// your view
)
}
}
Also yu need to make sure you use AppRegistry.registerComponent('glfm', () => Stacks); rather than AppRegistry.registerComponent('glfm', () => tapak);
The only answer to this question is to just put const { navigate } = this.props.navigation in your render() function and then you can use it in any component that you need
For Example
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
onPress={() => navigate('Profile', { name: 'Brent' })}
title="Go to Brent's profile"
/>
</View>
);
}
Please read this doc for https://reactnavigation.org/docs/en/navigation-prop.html

Why isn't React Native Drawer being triggered using React Native Router Flux + Redux?

I am using the following components to create a React Native + Redux app:
React Native Router Flux
React Native Drawer
I tried following exactly the example provided on how to implement the drawer, yet when navigating to where the drawer should be displayed, using Actions.drawer, I get the error:
But if I try to navigate to the Scene, via Actions.home, inside the drawer Scene, nothing happens but the action REACT_NATIVE_ROUTER_FLUX_RESET is still being called via redux-logger.
Tried following the example exactly but no luck. What could I be doing wrong?
Here is my set up for scene using Redux:
// #flow
import React, { Component } from 'react'
import {
ActionConst,
Actions,
Router,
Scene,
} from 'react-native-router-flux'
import {
Provider,
connect,
} from 'react-redux'
import configureStore from './store/configureStore'
import Login from './components/Login'
import Home from './components/Home'
import NavDrawer from './components/NavDrawer'
const RouterWithRedux = connect()(Router)
const store = configureStore()
export default class App extends Component {
render() {
return (
<Provider store={store}>
<RouterWithRedux>
<Scene key='root'>
<Scene component={Login} initial={true} key='login' title='Login'/>
<Scene key="drawer" component={NavDrawer}>
<Scene component={Home} key='home' title='Home' type='reset' initial={true}/>
</Scene>
</Scene>
</RouterWithRedux>
</Provider>
)
}
}
Then I press a button in Login and it triggers Actions. to navigate to.
The NavDrawer is:
import React, { PropTypes } from 'react'
import Drawer from 'react-native-drawer'
import { Actions, DefaultRenderer } from 'react-native-router-flux'
import NavDrawerPanel from './NavDrawerPanel'
export default class NavDrawer extends Component {
componentDidMount() {
Actions.refresh({key: 'drawer', ref: this.refs.navigation});
}
render() {
const children = state.children;
return (
<Drawer
ref="navigation"
type="displace"
content={<NavDrawerPanel />}
tapToClose
openDrawerOffset={0.2}
panCloseMask={0.2}
negotiatePan
tweenHandler={(ratio) => ({
main: { opacity: Math.max(0.54, 1 - ratio) },
})}
>
<DefaultRenderer
navigationState={children[0]}
onNavigate={this.props.onNavigate}
/>
</Drawer>
);
}
}
And NavDrawerPanel is:
import React from 'react';
import {PropTypes} from "react";
import {
StyleSheet,
Text,
View,
} from "react-native";
import { Actions } from 'react-native-router-flux';
const NavDrawerPanel = (props, context) => {
const drawer = context.drawer;
return (
<View style={styles.container}>
<TouchableHighlight onPress={Actions.home}>
<Text>Home Page</Text>
</TouchableHighlight>
<TouchableHighlight onPress={Actions.login}>
<Text>Login Page</Text>
</TouchableHighlight>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 30,
backgroundColor: 'black'
},
})
EDIT
Here are what's being imported where the Scene + Redux is set up:
// #flow
import React, { Component } from 'react'
import {
ActionConst,
Actions,
Router,
Scene,
} from 'react-native-router-flux'
import {
Provider,
connect,
} from 'react-redux'
import configureStore from './store/configureStore'
import Login from './components/Login'
import Home from './components/Home'
import NavDrawer from './components/NavDrawer'
EDIT 2 - console.log(this.props)
Doing console.log(this.props) in component Login:
When Actions.home() from component Login:
When Actions.drawer() from component Login:
EDIT 3 - console.log(this.props) inside NavDrawer.js
The NavDrawer never gets rendered so console.log(this.props) doesn't get logged
But with console.log(this.props) inside NavDrawer.js and Actions.home, I get:
And with console.log(this.props) inside NavDrawer.js and Actions.drawer, I get:
I'm not an expert in this but I'm using react-native-router-flux and react-native-drawer in my application without any problems. Some of the differences I see between your code and mine are:
You have two scenes set to initial={true}. This might mess up the Router.
I don't navigate directly to the drawer using Actions.drawer but instead I navigate to the home scene using Actions.home.
If nothing of these works, could you share the render() function of your home component?
Not sure if this is the issue but you don't seem to be importing TouchableHighlight on the NavDrawerPanel component, so:
import {
StyleSheet,
Text,
View,
TouchableHighlight
} from "react-native";
I think you pass in wrong value to navigationState in DefaultRenderer.
It should be
const { navigationState: { children } } = this.props;
In your NavDrawer class
import React, { PropTypes } from 'react'
import Drawer from 'react-native-drawer'
import { Actions, DefaultRenderer } from 'react-native-router-flux'
import NavDrawerPanel from './NavDrawerPanel'
export default class NavDrawer extends Component {
componentDidMount() {
Actions.refresh({key: 'drawer', ref: this.refs.navigation});
}
render() {
//const children = state.children; //wrong
const { navigationState: { children } } = this.props;
return (
<Drawer
ref="navigation"
type="displace"
content={<NavDrawerPanel />}
tapToClose
openDrawerOffset={0.2}
panCloseMask={0.2}
negotiatePan
tweenHandler={(ratio) => ({
main: { opacity: Math.max(0.54, 1 - ratio) },
})}
>
<DefaultRenderer
navigationState={children[0]}
onNavigate={this.props.onNavigate}
/>
</Drawer>
);
}
}
Not sure if this is still something you're working on, but for any others using these libraries, you definitely don't want to use the drawer as a scene. It should wrap you whole router like so:
<Drawer
ref={(ref) => { this.drawer = ref; }}
type="displace"
useInteractionManager
content={
<SideMenuContent
open={this.state.sideMenuOpen}
openDrawer={this.openDrawer}
closeDrawer={this.closeDrawer}
/>
}
tapToClose
openDrawerOffset={0.08}
negotiatePan
onOpenStart={() => { this.setState({ sideMenuOpen: true }); }}
onClose={() => { this.setState({ sideMenuOpen: false }); }}
>
<RouterWithRedux
scenes={this.scenes}
/>
</Drawer>
That's how we have it wired up, and it works well. Then, we just pass these function into our scenes as needed:
openDrawer = () => {
this.drawer.open();
}
closeDrawer = () => {
this.drawer.close();
}