How to route one page to another using react native? - react-native

I am building a very basic app for testing react native routing. Here my code...
index.android.js
constructor() {
super();
}
renderScene(route, navigator) {
if(route.name === 'loginPage') {
return <Login navigator={navigator}/>
} else if (route.name === 'homePage') {
alert('**********');
return <Home navigator={navigator}/>
}
}
render() {
return (
<Navigator
initialRoute={{name: 'loginPage' }}
renderScene= {(name) => this.renderScene(name)}
/>
);
}
Login Page
constructor() {
super();
this.navigate = this.navigate.bind(this)
}
navigate(name) {
this.props.navigate.push( {
name
})
}
render() {
return (
<Button
onPress={() => this.apiCalling('homePage')}
title="API Call"
accessibilityLabel="See an informative alert"
/>
);
}
}
but here I am getting error. The error is " undefined is not object ( evaluating 'this.props.navigator.push )
How may I resolve it...?

You are doing "this.props.navigate" while the prop being passed is called "navigator"

Related

How to redirect back and refresh the parent view

Hello everyone I am new to react-native.
React native V 0.61
React navigation V 5.x
I have a search bar for a weather API once it is clicked you arrive to the temperature list.
If you type an invalid city, I want to be redirected back with an error message. My problem is that I do not know how to do this because my parent component is not getting updated!
SEARCH.JS
export default class Search extends React.Component {
constructor(props){
super(props)
this.state = {
city: 'Liège',
error: ''
}
}
setCity(city){
this.setState({city})
}
submit(){
Keyboard.dismiss();
this.props.navigation.navigate('Result', {state: this.state});
}
render(){
if (this.state.error != '') {
var error = this.state.error;
} else {
var error = 'hello world';
}
return (
<View style={GlobalStyle.container}>
<TextInput
onChangeText={(text) => this.setCity(text)}
onSubmitEditing={() => this.submit()}
style={GlobalStyle.input}
value={this.state.city}
/>
<Button color={GlobalStyle.color} onPress={() => this.submit()} title="Lancé recherche"/>
<Text>{error}</Text>
</View>
);
}}
LIST.JS
export default class List extends React.Component {
constructor (props){
super(props)
this.state={
city: this.props.route.params.state.city,
result: null
}
this.fetchWeather();
}
fetchWeather(){
axios.get('http://api.openweathermap.org/data/2.5/forecast?q='+this.state.city+'&appid=MYKEY&units=metric&lang=fr')
.then((response) => {
this.props.route.params.state.error = '';
this.setState({result: response.data})
})
.catch(error => {
// console.log(error.response.data.message);
// console.log(this.props.navigation.setOptions());
// this.props.navigation.setParams.onReturn({city: this.props.route.params.state, error: error.response.data.message});
// this.props.state.error = 'errror';
this.props.route.params.state.error = error.response.data.message;
// console.log(this.props.route.params.state.error);
this.props.navigation.goBack();
// this.props.navigation.navigate('Search', {error: error.response.data.message});
});
}
render(){
if(this.state.result === null){
return (
<ActivityIndicator color={GlobalStyle.color} size="large"/>
);
}else{
return (
<FlatList
data={this.state.result.list}
renderItem={({item}) => <WeatherRow day={item}/>}
keyExtractor={item => item.dt.toString()}
/>
);
}
}}
Thank you for your help and have a good day.
In Search.js add
onBackToHome =() => {
this.setState({
city: 'Liège',
error: ''
})
}
submit(){
Keyboard.dismiss();
this.props.navigation.navigate('Result', {state: this.state, backToRefresh: this.onBackToHome});
}
Then in List.js
//Add this line just above this.props.navigation.goBack()
this.props.navigation.state.params.backToRefresh();

RN navigating from webview to a screen

I have the following RN code in my project. I want to navigate to a screen from where I have commented. Im inside a webview and if a condition is true, I want to navigate to a specific screen. Is there any way I can achieve this?
class CitizenLoginWebView extends Component {
render() {
return (
<WebView
source={{uri: citizenLoginUrl}}
onNavigationStateChange={navState => {
if (navState.title === "Consent Platform") {
if (hasWordsInString(navState.url, searchWords)) {
// WANT TO NAVIGATE TO A SCREEN FROM HERE
console.log('Words found');
}
}
}}
/>
);
}
}
class CitizenLoginWebView extends Component {
render() {
return (
<WebView
ref={'webview'}
source={{uri: citizenLoginUrl}}
onNavigationStateChange={navState => {
if (navState.title === "Consent Platform") {
if (hasWordsInString(navState.url, searchWords)) {
this.refs.webview.stopLoading();
this.props.navigation.navigate(screen);
console.log('Words found');
}
}
}}
/>
);
}
}
This would work if you use React-Navigation

React native : Is there any way to redirect the initial route to another page

I'm new in react native and currently developing a react-native app that require login. After successful login, the view change into Homepage. The problem is after i close and re-open the app, it shows me LoginPage again.Is there any way to redirect the initial route to another page
class Main extends Component {
_renderScene(route, navigator) {
if (route.id === 1) {
return <LoginPage navigator={navigator} />
} else if (route.id === 2) {
return <HomePage navigator={navigator} />
} else if (route.id === 3) {
return <DetailPage navigator={navigator} />
} else if (route.id === 4) {
return <CreateBookingPage navigator={navigator} />
}
}
_configureScene(route) {
return Navigator.SceneConfigs.PushFromRight;
}
render() {
return (
<Navigator
initialRoute={{id: 1, }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}
}
/////after some changes I get into this but still its rendering the login is I done something wrong////////
componentWillMount() {
AsyncStorage.getItem('key').then( (value) => {
if(value==="yes") {
this.setState({ loader: false, logged: true})
} else {
this.setState({ loader: false })
}
})
}
render() {
const routeId = this.state.logged ? 2 : 1;
if(this.state.loader) {
return (
<View /> // loading screen
);
}
return (
<Navigator
initialRoute={{id: routeId }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}
On successful login you could set a token/value in the local storage of the device and on logout clear this value.
You could check this value for setting the initial route. Asyncstorage can be used in setting and removing the logged status.
EDIT:
Initial state of loader should be true, logged should be false
componentWillMount() {
AsyncStorage.getItem('key').then( (value) => {
if(value) {
this.setState({ loader: false, logged: true})
} else {
this.setState({ loader: false })
}
})
}
render() {
const { loader } = this.state;
const routeId = logged ? 2 : 1;
if(loader) {
return (
<View /> // loading screen
);
}
return (
<Navigator
initialRoute={{id: routeId }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}
Replace with your render function and try it.
render() {
var loggedStatus = true; // change here for login screen
var routeId = loggedStatus ? 2 : 1;
return (
<Navigator
initialRoute={{id: routeId }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}

Navigator not passing parameters to scene

So, I have a simple button (TouchableHighlight) calling the following function:
showMovie() {
this.props.navigator.push({
name: 'MovieScreen',
index: 1,
movie: "terminator"
});
}
It works as expected, pushing the MovieScreen scene defined in a different file.
In the MovieScreen constructor I have:
constructor(props) {
super(props);
console.log(this.props.movie);
}
All I get is "undefined".
I tried with: console.log(this.props.passProps.movie); => undefined.
I tried putting the "movie" parameter in a passProps object => undefined.
I can't seem to pass parameters to a scene. If I print this.props I can't find anywhere the "movie" variable, but this.props is there and it contains the navigator object and everything.
Judging from the examples around the web, I'm doing exactly what thousands of people do, with the difference that mine doesn't work.
What I'm doing wrong?
More details as requested
This is how my app is composed:
index.android.js
HomepageScreen.js
MovieScreen.js
index.android.js
class MovieApp extends Component {
render() {
return (
<Navigator
initialRoute={{ name: 'HomepageScreen', title: 'My Initial Scene', index: 0 }}
renderScene={ this.renderScene }
/>
);
}
renderScene(route, navigator) {
if (route.name == 'HomepageScreen') {
return <HomepageScreen navigator={navigator} />
}
if (route.name == 'MovieScreen') {
return <MovieScreen navigator={navigator} />
}
}
}
HomepageScreen.js
export default class HomepageScreen extends Component {
constructor(props) {
super(props);
var navigator = this.props.navigator;
render() {
return(
<TouchableNativeFeedback onPress={this.showMovie.bind(this)}>
<View style={Style.movieButton}>
<Text style={Style.textStyle1}>Asd</Text>
</View>
</TouchableNativeFeedback>
);
}
showMovie() {
this.props.navigator.push({
name: 'MovieScreen',
index: 1,
movie: "terminator"
});
}
}
MovieScreen.js
export default class MovieScreen extends Component {
constructor(props) {
super(props);
console.log(this.props.movie);
}
.....
Try this:
renderScene(route, navigator) {
if (route.name == 'HomepageScreen') {
return <HomepageScreen navigator={navigator} {...route.passProps} />
}
if (route.name == 'MovieScreen') {
return <MovieScreen navigator={navigator} {...route.passProps} />
}
}
And passing the props like this:
this.props.navigator.push({
name: 'MovieScreen',
index: 1,
passProps: {
movie: "terminator"
}
});

Implement FB login with react native and redux

I want to use Redux framework in my react native based app for implementing Facebook login (I am learning Redux at the moment). I am looking for suggestions on how to structure my Facebook login code to use the redux. More specifically, what actions, reducer and store should I create?
Below is the current Facebook based login code that I have in my app (it does not use redux structure). I have deleted the unrelated code to keep things simple:
index.ios.js
class ProjectXApp extends React.Component {
constructor(props) {
// Set the use to NULL
this.state = {
user: null,
};
}
handleLogin(user) {
this.setState({
// Update the user state once the login is complete
user,
});
}
renderScene(route, navigator) {
const Component = route.component;
return (
<View style={styles.app}>
<Component
user={this.state.user}
navigator={navigator}
route={route}
/>
</View>
);
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
initialRoute={{
// Render the Login page in the beginning
component: Login,
props: {
onLogin: this.handleLogin.bind(this),
},
}}
/>
);
}
}
Login.js
// Import Facebook Login Util Component
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
// 'false' means responseToken is not required. 'true' means responseToken is required
responseToken: false,
};
}
// This method gets the fb access token, if the token is returned then
// I render the Main App component (switchToMain method). If the
// access token is not returned then I render a login Button (Refer to render method)
async getAccessToken() {
let _this = this;
await (FBSDKAccessToken.getCurrentAccessToken((token) => {
if(!token) {
_this.setState({responseToken: true})
return;
}
_this.setState({responseToken: true});
_this.props.route.props.onLogin({user: true});
_this.switchToMain();
}));
}
switchToMain() {
this.props.navigator.push({
component: Main, // Render the app
props: {
onLogOut: this.onLogOut.bind(this)
}
});
}
componentDidMount() {
this.getAccessToken();
}
onLoginButtonPress() {
// Shows transition between login and Main Screen
this.setState({responseToken: false})
FBSDKLoginManager.logInWithReadPermissions(['public_profile','email','user_friends'], (error, result) => {
if (error) {
alert('Error logging in');
} else {
if (result.isCancelled) {
alert('Login cancelled');
} else {
this.setState({result});
this.getAccessToken();
}
}
});
}
onLogOut() {
this.setState({responseToken: true});
}
render() {
// This component renders when I am calling getAccessToken method
if(!this.state.responseToken) {
return (
<Text></Text>
);
}
// This renders when access token is not available after calling getAccessToken
return (
<View style={styles.container}>
<TouchableHighlight
onPress={this.onLoginButtonPress.bind(this)}
>
<View>
// Login Button
</View>
</TouchableHighlight>
</View>
);
}
}
// Removed the styling code
Logout.js
import { FBSDKLoginManager } from 'react-native-fbsdklogin';
class Logout extends React.Component {
onLogOut() {
FBSDKLoginManager.logOut();
this.props.onLogOut();
this.props.navigator.popToTop();
}
render() {
return (
<View>
<TouchableHighlight
onPress={this.onLogOut.bind(this)}
>
<View
// Styles to create Logout button
</View>
</TouchableHighlight>
</View>
);
}
});
// Removed the styling code
Have you looked at this lib:
https://github.com/lynndylanhurley/redux-auth?