admin管理员组文章数量:1023221
I would like to make my app move to the next page when a code is entered correctly, but I have been having much trouble doing so. I am working in a file names AccessForm.js , which is not a screen but is a ponent that is included in the access code screen. I tried using this.props.navigation.navigate('CreateAccountScreen');
, but ran into the error "Undefined is not an object (evaluating 'this.props.navigation'). With some trial and error, I found out that I can only use react-navigation inside of an actual screen for some weird reason. After this, I made an attempt to use this.state
and this.setState({})
to keep track of a screen variable, and sync it to the actual access code screen, so i could use navigation. Unfortunately, this.setState
also throws a "Undefined is not an object" error. I have pasted an abbreviated version of my code below. What would be the best way to achieve this navigating outside of a screen file issue?
App.js ---->
import { createStackNavigator, createAppContainer } from 'react-navigation';
import AccessScreen from './src/screens/AccessScreen';
import CreateAccountScreen from './src/screens/CreateAccountScreen';
const RootStack = createStackNavigator ({
EnterAccessCode : {
screen: AccessScreen
},
CreateAccount : {
screen: CreateAccountScreen
}
},
{
headerMode: 'none'
});
const App = createAppContainer(RootStack);
export default App;
AccessForm.js ---->
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require("firebase");
if (!firebase.apps.length) { // Don't open more than one firebase session
firebase.initializeApp({ // Initialize firebase connection
apiKey: "key",
authDomain: "domain",
databaseURL: "url",
storageBucket: "storage_bucket",
});
}
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
// this.state = {
// screen: 0
// };
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
//this.checkCode = this.checkCode.bind(this); // throws error
}
render() {
return (
<View style={styles.container} >
<TextInput
style={styles.input}
placeholder='Access Code'
returnKeyType='go'
onSubmitEditing={(text) => checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize='none'
autoCorrect={false}
/>
</View>
);
}
}
function checkCode(text) {
var code = text; // Set entered code to the var "code"
var identifier = ""; // Used to store unique code object identifier
codesRef.once('value', function(db_snapshot) {
let codeIsFound = false
db_snapshot.forEach(function(code_snapshot) { // Cycle through available codes in db
if (code == code_snapshot.val().value) { // Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
})
if (codeIsFound) {
deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccountScreen');
//this.setState({screen: 1}); // this throws error
// MOVE TO NEXT SCREEN
//this.props.navigation.navigate('AccountCreateScreen'); // throws error
} else { // wrong code
// note to self : add error message based on state var
AlertIOS.alert("We're Sorry...", "The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.");
}
});
}
function deleteCode(id) { // delete a code from unique ID
firebase.database().ref('codes/' + id).remove();
}
// stylesheet is below
Login.js ---->
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput, KeyboardAvoidingView, Platform } from 'react-native';
import AccessForm from './AccessForm';
export default class App extends React.Component {
render() {
return (
<View>
<View style={styles.logoContainer}>
<Image
source={require('../images/mhs.jpg')}
style={styles.logo}
/>
<Text style={styles.app_title}>MHS-Protect</Text>
<Text>An app to keep MHS safe and in-touch.</Text>
</View>
<KeyboardAvoidingView style={styles.container} behavior='padding'>
<View style ={styles.formContainer}>
<AccessForm/>
</View>
</KeyboardAvoidingView>
</View>
);
}
}
//styles below
I would like to make my app move to the next page when a code is entered correctly, but I have been having much trouble doing so. I am working in a file names AccessForm.js , which is not a screen but is a ponent that is included in the access code screen. I tried using this.props.navigation.navigate('CreateAccountScreen');
, but ran into the error "Undefined is not an object (evaluating 'this.props.navigation'). With some trial and error, I found out that I can only use react-navigation inside of an actual screen for some weird reason. After this, I made an attempt to use this.state
and this.setState({})
to keep track of a screen variable, and sync it to the actual access code screen, so i could use navigation. Unfortunately, this.setState
also throws a "Undefined is not an object" error. I have pasted an abbreviated version of my code below. What would be the best way to achieve this navigating outside of a screen file issue?
App.js ---->
import { createStackNavigator, createAppContainer } from 'react-navigation';
import AccessScreen from './src/screens/AccessScreen';
import CreateAccountScreen from './src/screens/CreateAccountScreen';
const RootStack = createStackNavigator ({
EnterAccessCode : {
screen: AccessScreen
},
CreateAccount : {
screen: CreateAccountScreen
}
},
{
headerMode: 'none'
});
const App = createAppContainer(RootStack);
export default App;
AccessForm.js ---->
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require("firebase");
if (!firebase.apps.length) { // Don't open more than one firebase session
firebase.initializeApp({ // Initialize firebase connection
apiKey: "key",
authDomain: "domain",
databaseURL: "url",
storageBucket: "storage_bucket",
});
}
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
// this.state = {
// screen: 0
// };
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
//this.checkCode = this.checkCode.bind(this); // throws error
}
render() {
return (
<View style={styles.container} >
<TextInput
style={styles.input}
placeholder='Access Code'
returnKeyType='go'
onSubmitEditing={(text) => checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize='none'
autoCorrect={false}
/>
</View>
);
}
}
function checkCode(text) {
var code = text; // Set entered code to the var "code"
var identifier = ""; // Used to store unique code object identifier
codesRef.once('value', function(db_snapshot) {
let codeIsFound = false
db_snapshot.forEach(function(code_snapshot) { // Cycle through available codes in db
if (code == code_snapshot.val().value) { // Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
})
if (codeIsFound) {
deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccountScreen');
//this.setState({screen: 1}); // this throws error
// MOVE TO NEXT SCREEN
//this.props.navigation.navigate('AccountCreateScreen'); // throws error
} else { // wrong code
// note to self : add error message based on state var
AlertIOS.alert("We're Sorry...", "The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.");
}
});
}
function deleteCode(id) { // delete a code from unique ID
firebase.database().ref('codes/' + id).remove();
}
// stylesheet is below
Login.js ---->
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput, KeyboardAvoidingView, Platform } from 'react-native';
import AccessForm from './AccessForm';
export default class App extends React.Component {
render() {
return (
<View>
<View style={styles.logoContainer}>
<Image
source={require('../images/mhs.jpg')}
style={styles.logo}
/>
<Text style={styles.app_title}>MHS-Protect</Text>
<Text>An app to keep MHS safe and in-touch.</Text>
</View>
<KeyboardAvoidingView style={styles.container} behavior='padding'>
<View style ={styles.formContainer}>
<AccessForm/>
</View>
</KeyboardAvoidingView>
</View>
);
}
}
//styles below
Share
Improve this question
edited Apr 22, 2019 at 2:36
Michael Hoefler
asked Apr 22, 2019 at 1:12
Michael HoeflerMichael Hoefler
932 silver badges12 bronze badges
5
-
1.
import { withNavigation } from 'react-navigation';
2. Removeexport default
from your class. 3. At the bottom doexport default withNavigation(LoginForm)
– Ziyo Commented Apr 22, 2019 at 1:49 - @Ziyo I think I’m close but this still throws “undefined is not an object (evaluating this.props.navigation)” – Michael Hoefler Commented Apr 22, 2019 at 1:58
-
Oh no.
checkCode
function should be a method of LoginForm – Ziyo Commented Apr 22, 2019 at 2:01 -
if you put checkCode inside the class, you don't need to do
withNavigation
thing. – Ziyo Commented Apr 22, 2019 at 2:02 - I will post it as an answer below. – Ziyo Commented Apr 22, 2019 at 2:09
3 Answers
Reset to default 2
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require('firebase');
if (!firebase.apps.length) {
// Don't open more than one firebase session
firebase.initializeApp({
// Initialize firebase connection
apiKey: 'key',
authDomain: 'domain',
databaseURL: 'url',
storageBucket: 'storage_bucket',
});
}
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
}
checkCode = text => {
var code = text; // Set entered code to the var "code"
var identifier = ''; // Used to store unique code object identifier
this.codesRef.once('value', function(db_snapshot) {
let codeIsFound = false;
db_snapshot.forEach(function(code_snapshot) {
// Cycle through available codes in db
if (code == code_snapshot.val().value) {
// Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
});
if (codeIsFound) {
this.deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccount');
} else {
// wrong code
// note to self : add error message based on state var
AlertIOS.alert(
"We're Sorry...",
'The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.'
);
}
});
};
deleteCode = id => {
firebase
.database()
.ref('codes/' + id)
.remove();
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Access Code"
returnKeyType="go"
onSubmitEditing={text => this.checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize="none"
autoCorrect={false}
/>
</View>
);
}
}
You should have navigation
object in your props. By default, react navigation will pass navigation
to all screens but other ponents. To do this, you have two options:
1. Pass navigation
props from your screen to every child ponents (not remended).
2. Use withNavigation
as mention in document here https://reactnavigation/docs/en/connecting-navigation-prop.html
import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
}
}
// withNavigation returns a ponent that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);
Edit:
The checkCode
method does not belong to your LoginForm
. You need to:
1. Make it part of LoginForm .
2. Remember to use bind
or arrow function
definition. Otherwise, your this
inside function is not defined.
import { withNavigation } from 'react-navigation';
class LoginForm extends React.Component {
checkCode = (text) => {
....
};
}
export default withNavigation(LoginForm);
You can read more about bind
or arrow method here https://medium./shoutem/react-to-bind-or-not-to-bind-7bf58327e22a
Copy and paste(Reference) from: https://github./react-navigation/react-navigation/issues/1439#issuement-303661539
It works from me.
you can pass your top-level navigator ref to a service, and dispatch actions from that service.
// App.js
import NavigatorService from './services/navigator';
const Navigator = StackNavigator({ /* ... */ })
class App extends Component {
// ...
render(): {
return (
<Navigator
ref={navigatorRef => {
NavigatorService.setContainer(navigatorRef);
}}
/>
);
}
}
// services/navigator.js
// @flow
import { NavigationActions } from 'react-navigation';
import type { NavigationParams, NavigationRoute } from 'react-navigation';
let _container; // eslint-disable-line
function setContainer(container: Object) {
_container = container;
}
function reset(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName,
params,
}),
],
}),
);
}
function navigate(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName,
params,
}),
);
}
function navigateDeep(actions: { routeName: string, params?: NavigationParams }[]) {
_container.dispatch(
actions.reduceRight(
(prevAction, action): any =>
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName: action.routeName,
params: action.params,
action: prevAction,
}),
undefined,
),
);
}
function getCurrentRoute(): NavigationRoute | null {
if (!_container || !_container.state.nav) {
return null;
}
return _container.state.nav.routes[_container.state.nav.index] || null;
}
export default {
setContainer,
navigateDeep,
navigate,
reset,
getCurrentRoute,
};
and then you can use Navigator service everywhere.
Like:
import NavigatorService from './services/navigator';
NavigatorService.navigate('Home');
I would like to make my app move to the next page when a code is entered correctly, but I have been having much trouble doing so. I am working in a file names AccessForm.js , which is not a screen but is a ponent that is included in the access code screen. I tried using this.props.navigation.navigate('CreateAccountScreen');
, but ran into the error "Undefined is not an object (evaluating 'this.props.navigation'). With some trial and error, I found out that I can only use react-navigation inside of an actual screen for some weird reason. After this, I made an attempt to use this.state
and this.setState({})
to keep track of a screen variable, and sync it to the actual access code screen, so i could use navigation. Unfortunately, this.setState
also throws a "Undefined is not an object" error. I have pasted an abbreviated version of my code below. What would be the best way to achieve this navigating outside of a screen file issue?
App.js ---->
import { createStackNavigator, createAppContainer } from 'react-navigation';
import AccessScreen from './src/screens/AccessScreen';
import CreateAccountScreen from './src/screens/CreateAccountScreen';
const RootStack = createStackNavigator ({
EnterAccessCode : {
screen: AccessScreen
},
CreateAccount : {
screen: CreateAccountScreen
}
},
{
headerMode: 'none'
});
const App = createAppContainer(RootStack);
export default App;
AccessForm.js ---->
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require("firebase");
if (!firebase.apps.length) { // Don't open more than one firebase session
firebase.initializeApp({ // Initialize firebase connection
apiKey: "key",
authDomain: "domain",
databaseURL: "url",
storageBucket: "storage_bucket",
});
}
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
// this.state = {
// screen: 0
// };
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
//this.checkCode = this.checkCode.bind(this); // throws error
}
render() {
return (
<View style={styles.container} >
<TextInput
style={styles.input}
placeholder='Access Code'
returnKeyType='go'
onSubmitEditing={(text) => checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize='none'
autoCorrect={false}
/>
</View>
);
}
}
function checkCode(text) {
var code = text; // Set entered code to the var "code"
var identifier = ""; // Used to store unique code object identifier
codesRef.once('value', function(db_snapshot) {
let codeIsFound = false
db_snapshot.forEach(function(code_snapshot) { // Cycle through available codes in db
if (code == code_snapshot.val().value) { // Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
})
if (codeIsFound) {
deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccountScreen');
//this.setState({screen: 1}); // this throws error
// MOVE TO NEXT SCREEN
//this.props.navigation.navigate('AccountCreateScreen'); // throws error
} else { // wrong code
// note to self : add error message based on state var
AlertIOS.alert("We're Sorry...", "The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.");
}
});
}
function deleteCode(id) { // delete a code from unique ID
firebase.database().ref('codes/' + id).remove();
}
// stylesheet is below
Login.js ---->
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput, KeyboardAvoidingView, Platform } from 'react-native';
import AccessForm from './AccessForm';
export default class App extends React.Component {
render() {
return (
<View>
<View style={styles.logoContainer}>
<Image
source={require('../images/mhs.jpg')}
style={styles.logo}
/>
<Text style={styles.app_title}>MHS-Protect</Text>
<Text>An app to keep MHS safe and in-touch.</Text>
</View>
<KeyboardAvoidingView style={styles.container} behavior='padding'>
<View style ={styles.formContainer}>
<AccessForm/>
</View>
</KeyboardAvoidingView>
</View>
);
}
}
//styles below
I would like to make my app move to the next page when a code is entered correctly, but I have been having much trouble doing so. I am working in a file names AccessForm.js , which is not a screen but is a ponent that is included in the access code screen. I tried using this.props.navigation.navigate('CreateAccountScreen');
, but ran into the error "Undefined is not an object (evaluating 'this.props.navigation'). With some trial and error, I found out that I can only use react-navigation inside of an actual screen for some weird reason. After this, I made an attempt to use this.state
and this.setState({})
to keep track of a screen variable, and sync it to the actual access code screen, so i could use navigation. Unfortunately, this.setState
also throws a "Undefined is not an object" error. I have pasted an abbreviated version of my code below. What would be the best way to achieve this navigating outside of a screen file issue?
App.js ---->
import { createStackNavigator, createAppContainer } from 'react-navigation';
import AccessScreen from './src/screens/AccessScreen';
import CreateAccountScreen from './src/screens/CreateAccountScreen';
const RootStack = createStackNavigator ({
EnterAccessCode : {
screen: AccessScreen
},
CreateAccount : {
screen: CreateAccountScreen
}
},
{
headerMode: 'none'
});
const App = createAppContainer(RootStack);
export default App;
AccessForm.js ---->
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require("firebase");
if (!firebase.apps.length) { // Don't open more than one firebase session
firebase.initializeApp({ // Initialize firebase connection
apiKey: "key",
authDomain: "domain",
databaseURL: "url",
storageBucket: "storage_bucket",
});
}
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
// this.state = {
// screen: 0
// };
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
//this.checkCode = this.checkCode.bind(this); // throws error
}
render() {
return (
<View style={styles.container} >
<TextInput
style={styles.input}
placeholder='Access Code'
returnKeyType='go'
onSubmitEditing={(text) => checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize='none'
autoCorrect={false}
/>
</View>
);
}
}
function checkCode(text) {
var code = text; // Set entered code to the var "code"
var identifier = ""; // Used to store unique code object identifier
codesRef.once('value', function(db_snapshot) {
let codeIsFound = false
db_snapshot.forEach(function(code_snapshot) { // Cycle through available codes in db
if (code == code_snapshot.val().value) { // Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
})
if (codeIsFound) {
deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccountScreen');
//this.setState({screen: 1}); // this throws error
// MOVE TO NEXT SCREEN
//this.props.navigation.navigate('AccountCreateScreen'); // throws error
} else { // wrong code
// note to self : add error message based on state var
AlertIOS.alert("We're Sorry...", "The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.");
}
});
}
function deleteCode(id) { // delete a code from unique ID
firebase.database().ref('codes/' + id).remove();
}
// stylesheet is below
Login.js ---->
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput, KeyboardAvoidingView, Platform } from 'react-native';
import AccessForm from './AccessForm';
export default class App extends React.Component {
render() {
return (
<View>
<View style={styles.logoContainer}>
<Image
source={require('../images/mhs.jpg')}
style={styles.logo}
/>
<Text style={styles.app_title}>MHS-Protect</Text>
<Text>An app to keep MHS safe and in-touch.</Text>
</View>
<KeyboardAvoidingView style={styles.container} behavior='padding'>
<View style ={styles.formContainer}>
<AccessForm/>
</View>
</KeyboardAvoidingView>
</View>
);
}
}
//styles below
Share
Improve this question
edited Apr 22, 2019 at 2:36
Michael Hoefler
asked Apr 22, 2019 at 1:12
Michael HoeflerMichael Hoefler
932 silver badges12 bronze badges
5
-
1.
import { withNavigation } from 'react-navigation';
2. Removeexport default
from your class. 3. At the bottom doexport default withNavigation(LoginForm)
– Ziyo Commented Apr 22, 2019 at 1:49 - @Ziyo I think I’m close but this still throws “undefined is not an object (evaluating this.props.navigation)” – Michael Hoefler Commented Apr 22, 2019 at 1:58
-
Oh no.
checkCode
function should be a method of LoginForm – Ziyo Commented Apr 22, 2019 at 2:01 -
if you put checkCode inside the class, you don't need to do
withNavigation
thing. – Ziyo Commented Apr 22, 2019 at 2:02 - I will post it as an answer below. – Ziyo Commented Apr 22, 2019 at 2:09
3 Answers
Reset to default 2
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require('firebase');
if (!firebase.apps.length) {
// Don't open more than one firebase session
firebase.initializeApp({
// Initialize firebase connection
apiKey: 'key',
authDomain: 'domain',
databaseURL: 'url',
storageBucket: 'storage_bucket',
});
}
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
}
checkCode = text => {
var code = text; // Set entered code to the var "code"
var identifier = ''; // Used to store unique code object identifier
this.codesRef.once('value', function(db_snapshot) {
let codeIsFound = false;
db_snapshot.forEach(function(code_snapshot) {
// Cycle through available codes in db
if (code == code_snapshot.val().value) {
// Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
});
if (codeIsFound) {
this.deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccount');
} else {
// wrong code
// note to self : add error message based on state var
AlertIOS.alert(
"We're Sorry...",
'The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.'
);
}
});
};
deleteCode = id => {
firebase
.database()
.ref('codes/' + id)
.remove();
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Access Code"
returnKeyType="go"
onSubmitEditing={text => this.checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize="none"
autoCorrect={false}
/>
</View>
);
}
}
You should have navigation
object in your props. By default, react navigation will pass navigation
to all screens but other ponents. To do this, you have two options:
1. Pass navigation
props from your screen to every child ponents (not remended).
2. Use withNavigation
as mention in document here https://reactnavigation/docs/en/connecting-navigation-prop.html
import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
}
}
// withNavigation returns a ponent that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);
Edit:
The checkCode
method does not belong to your LoginForm
. You need to:
1. Make it part of LoginForm .
2. Remember to use bind
or arrow function
definition. Otherwise, your this
inside function is not defined.
import { withNavigation } from 'react-navigation';
class LoginForm extends React.Component {
checkCode = (text) => {
....
};
}
export default withNavigation(LoginForm);
You can read more about bind
or arrow method here https://medium./shoutem/react-to-bind-or-not-to-bind-7bf58327e22a
Copy and paste(Reference) from: https://github./react-navigation/react-navigation/issues/1439#issuement-303661539
It works from me.
you can pass your top-level navigator ref to a service, and dispatch actions from that service.
// App.js
import NavigatorService from './services/navigator';
const Navigator = StackNavigator({ /* ... */ })
class App extends Component {
// ...
render(): {
return (
<Navigator
ref={navigatorRef => {
NavigatorService.setContainer(navigatorRef);
}}
/>
);
}
}
// services/navigator.js
// @flow
import { NavigationActions } from 'react-navigation';
import type { NavigationParams, NavigationRoute } from 'react-navigation';
let _container; // eslint-disable-line
function setContainer(container: Object) {
_container = container;
}
function reset(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName,
params,
}),
],
}),
);
}
function navigate(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName,
params,
}),
);
}
function navigateDeep(actions: { routeName: string, params?: NavigationParams }[]) {
_container.dispatch(
actions.reduceRight(
(prevAction, action): any =>
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName: action.routeName,
params: action.params,
action: prevAction,
}),
undefined,
),
);
}
function getCurrentRoute(): NavigationRoute | null {
if (!_container || !_container.state.nav) {
return null;
}
return _container.state.nav.routes[_container.state.nav.index] || null;
}
export default {
setContainer,
navigateDeep,
navigate,
reset,
getCurrentRoute,
};
and then you can use Navigator service everywhere.
Like:
import NavigatorService from './services/navigator';
NavigatorService.navigate('Home');
本文标签: javascriptHow to use react navigation outside of a screenStack Overflow
版权声明:本文标题:javascript - How to use react navigation outside of a screen - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745543598a2155292.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论