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

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; }} />
);
}

Related

How to add a condition for the user's connection?

I want to add to this code the condition: if the user is connected, he goes directly to BottomTabNavigator (which is the opening of the application) and otherwise he goes in the Authentication file which will allow him to either connect or register. How can I do this ?
Usually I used
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import BottomTabNavigator from "./Navigation/TabNavigator";
const App = () => {
return (
<NavigationContainer>
<BottomTabNavigator />
</NavigationContainer>
);
}
export default App
Usually in a class component I used this, but I don't know how to do with the new syntax:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isFirstConnection: true,
status: 0,
fontLoaded: false
};
}
async UNSAFE_componentWillMount() {
let lang = await retrieveAppLang();
let isConnected = await userSessionActive();
if (lang.length == 2) {
i18n.changeLanguage(lang);
}
if (isConnected === true && this.props && this.props.navigation) {
this.props.navigation.navigate("TabBar");
}
}
async componentDidMount() {
await Font.loadAsync({
FunctionLH: require("./assets/fonts/FunctionLH-Light.ttf")
});
const data = await this.performTimeConsumingTask();
if (data !== null) {
this.setState({
isFirstConnection: false,
status: 1,
fontLoaded: true,
});
}
}
performTimeConsumingTask = async () => {
return new Promise((resolve) =>
setTimeout(() => {
resolve("result");
}, 750)
);
};
render() {
if (this.state.status == 1) {
if (this.state.isFirstConnection && this.state.fontLoaded) {
return <SplashScreen />;
} else {
return <Navigation screenProps={'Authentication'} />;
}
}
return (
<ImageBackground
source={require("./assets/images/background.jpg")}
style={{ flex: 1 }}
>
<View style={[styles2.container, styles2.containerCentered]}>
<StatusBar hidden={true} />
<View style={styles2.subContainer}>
<Image
style={styles2.logo}
source={require("./assets/images/logo.png")}
/>
<ActivityIndicator size="large" color="#43300E" />
<Text>{i18n.t("app.loading") + "..."}</Text>
</View>
</View>
</ImageBackground>
);
}
}}
the 'isConnected' is on a file "myPreferences"
export async function userSessionActive() {
let userAuthorizationCode = await retrieveProfileAuthorizationCode();
let userUserId = await retrieveProfileUserId();
let userEmail = await retrieveProfileLogin();
let is_connected = false;
if (userAuthorizationCode != '' && userUserId !== null && parseInt(userUserId) > 0 && userEmail != '') {
is_connected = true;
}
return is_connected;
}
I thought doing something like this but it's not working :
function App(userSessionActive) {
const isConnected = userSessionActive.isConnected;
if (isConnected) {
return <NavigationContainer>
<BottomTabNavigator />
</NavigationContainer>;
}
return <StackNavigator screenProps={'Authentication'}/>;
}
export default App

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();

state undefined in react-native redux

I am implementing redux in react-native project. I have some asyn action and some pure actions. I am unable to get state value in my component. How do I get it.?
class Gender extends Component {
constructor(props) {
super(props);
}
nextScr = (gend) => {
alert(`gen: ${gend} \n this.props.gen: ${this.props.gen}`)
//***** here I am getting undefined ****
if(gend!= null) {
this.props.navigation.navigate('Info');
}
}
render() {
const { gen } = this.props;
return (
<View style={style.container}>
<View style={style.bcont}>
{/* this.storeData("Male") this.storeData("Female") */}
<Btn name="gender-male" txt="Male" click={() => this.props.saveMale('male')}
bstyl={(gen == 'Male') ? [style.btn, style.btnsel] : style.btn} />
<Text style={style.hi}>OR</Text>
<Btn name="gender-female" txt="Female" click={() => this.props.saveFemale('female')}
bstyl={(gen == 'Female') ? [style.btn, style.btnsel] : style.btn} />
</View>
<Text>Gender Value is: {this.props.gen}</Text>
// **** here not getting gen value ****
<Next name="chevron-right" nextClk={ () => this.nextScr(gen)} />
</View>
);
}
}
const mapStateToProps = state => {
const { gen } = state
return {
gen: gen,
};
};
const mapDispatchToProps = dispatch => {
return {
saveMale: (gen) => {
dispatch(saveMale(gen));
},
saveFemale: (gen) => {
dispatch(saveFemale(gen));
}
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Gender);
These are my actions:
export const saveMale = (gen) => ({
type: MALE_SAVE,
payload: gen
});
export const saveFemale = (gen) => ({
type: FEMALE_SAVE,
payload: gen
});
Following is my reducer:
const initialState = {
gen: null
}
export function genSave(state=initialState, action) {
switch(action.type) {
case MALE_SAVE:
alert(`state in MALE_SAVE: ${action.payload}`);
return { ...state, gen: action.payload };
case FEMALE_SAVE:
alert(`state in FEMALE_SAVE: ${action.payload}`);
return { ...state, gen: action.payload };
default:
alert(`state in default gender save: ${JSON.stringify(state)}`);
return state;
};
}
I am getting action.payload alert values but in the component I am not getting values. How do I solve this problem ?? Thanks in advance.
Can you try like this?
...
nextScr(gend) {
alert(`gen: ${gend} \n this.props.gen: ${this.props.gen}`)
if(gend!= null) {
this.props.navigation.navigate('Info');
}
}
render() {
const { gen } = this.props;
return (
<View style={style.container}>
<View style={style.bcont}>
{/* this.storeData("Male") this.storeData("Female") */}
<Btn name="gender-male" txt="Male" click={() => this.props.saveMale('male')}
bstyl={(gen == 'Male') ? [style.btn, style.btnsel] : style.btn} />
<Text style={style.hi}>OR</Text>
<Btn name="gender-female" txt="Female" click={() => this.props.saveFemale('female')}
bstyl={(gen == 'Female') ? [style.btn, style.btnsel] : style.btn} />
</View>
<Text>Gender Value is: {this.props.gen}</Text>
<Next name="chevron-right" nextClk={ () => this.nextScr(this.props.gen)} />
</View>
);
}
...
I believe your mapStateToProps could be the problem depending on how you initialize your store. Right now it assumes gen is a property on the base store but it is likely you have a combineRecucers call when you create the store that adds another object layer.

Is there any way to display <Text> with a timer setTimeout() multiple times?

I'm trying to return 9 differents Text with a 5 seconds delay between each ones but it's only working for the first Text
i've tried using
render() {
setTimeout(() => {this.setState({timePassed: true})}, 2000);
if(this.state.timePassed == false){
return (
<Text></Text>
)
}else if (this.state.timePassed == true{
return(
<Text>HELLO</Text>
)
}else if (this.state.timePassed1 == false{
............
}
}
but not working
I have also tried
componentDidUpdate(){
setTimeout(() => {this.setState({timePassed1: true})}, 4000);
if(this.state.timePassed1 == true){
return(
<Text>test</Text>)
}
}
but not working
Here is my screen
export default class Internet2 extends React.Component {
constructor(props){
super(props);
this.state = {
timePassed: false,
timePassed1: false
};
}
componentDidUpdate(){
setTimeout(() => {this.setState({timePassed1: true})}, 4000);
if(this.state.timePassed1 == true){
return(
<Text>test</Text>)
}
}
render() {
setTimeout(() => {this.setState({timePassed: true})}, 2000);
if(this.state.timePassed == false){
return (
<Text></Text>
)
}else{
return(
<Text>HELLO</Text>
)
}
}
}
Thank you for your help !
What you can do is keep the texts in an array and a variable for counting how many times has it passed.
state = {
texts = ['sometext', ...]
textCount = 0
}
Then you will create a setInterval to loop in the time you want
componentDidMount() {
let timer = setInterval(() => {
this.setState(prevState => {
return {textCount: prevState.textCount + 1}
})
if (this.state.textCount > this.state.texts.length) clearInterval(timer);
}, theTimeYouWant);
}
And render the texts using .map
render() {
return (
<View>
{this.state.texts.map((text, i) => i <= this.state.textCount ?
<Text>{text}</Text> : null
)}
</View>
)
}
I found the solution, its in render and you have to go like:
constructor(props){
super(props);
this.state = {
timePassed: false,
timePassed1: false
};
}
render() {
setTimeout(() => {this.setState({timePassed: true})}, 2000);
setTimeout(() => {this.setState({timePassed1: true})}, 3000);
return (
<View>
{this.state.timePassed == true ? (<Text>INTERNET</Text>) : null}
{this.state.timePassed1 == true ? (<Text>TEST</Text>) : null}
</View>
)
}
}

How to route one page to another using 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"