Navigating back to start screen - react-native

I have two different documents with two different screens. After an e-mail validation on the first screen, I'm now able to go to the second screen. However, I want to return to the first screen. None of the mentioned approaches on the React Navigation 5.x documentation works for me.
This is the code on the App.js:
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import firebase from './firebase';
import * as EmailValidator from 'email-validator';
import { HitTestResultTypes } from 'expo/build/AR';
import logo from './assets/Circulo.png';
import AgeInput from './AgeInput';
// Clase que representa el diseño de la pantalla inicial de la app
class HomeScreen extends Component {
state = { username: null, password: null, nonValidInput: null }
_onSubmit = ({ navigation }) =>{
if(EmailValidator.validate(this.state.username) == true) {
this.setState({ nonValidInput: false });
const { username, password } = this.state;
try {
// THIS IS WHERE I GO TO THE SECOND SCREEN
firebase.auth().signInWithEmailAndPassword(this.state.username, this.state.password).then(() => this.props.navigation.navigate('Age'));
} catch {
Alert.alert(
'Error',
'Los datos no son correctos',
[
{ text: 'Ok' }
],
{ cancelable: false }
);
}
} else {
this.setState({ nonValidInput: true });
}
}
render() {
return (
<KeyboardAwareScrollView contentContainerStyle={styles.container} scrollEnabled
enableOnAndroid={true} resetScrollToCoords={{x:0, y:0}}>
<View style={styles.logo}>
<Image source = {logo} style={styles.img}/>
<Text style={styles.textLogoPrimary}>Neuron App</Text>
<Text style={styles.textLogoSecondary}>Test</Text>
</View>
<View style={styles.formElement}>
<Text style={styles.formText}>Correo Electrónico</Text>
<TextInput keyboardType='email-address' placeholder='Email' onChangeText={value => this.setState({ username: value })}
style={styles.formInput} />
{this.state.nonValidInput ? (
<Text style={styles.textAlert}>Correo electrónico no valido.</Text>
) : null}
</View>
<View style={styles.formElement}>
<Text style={styles.formText}>Contraseña</Text>
<TextInput style={styles.formInput} placeholder='Contraseña' onChangeText={value => this.setState({ password: value })}
secureTextEntry={true}/>
</View>
<View style={styles.buttonView}>
<TouchableOpacity style={styles.button} onPress={this._onSubmit}>
<Text style={styles.buttonText}>Iniciar</Text>
</TouchableOpacity>
</View>
</KeyboardAwareScrollView>
);
}
}
const Stack = createStackNavigator();
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}} initialRouteName="Home">
<Stack.Screen name='Home' component={HomeScreen} />
<Stack.Screen name='Age' component={AgeInput} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
and this is the code on the AgeInput.js
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Home from './App';
class App extends Component { // AgeInput
state = { date: null, edad: null, day: null, month: null, year: null }
_ageCalc = () => {
if(this.state.day < 32 && this.state.day > 0 && this.state.month < 13 && this.state.month > 0 && this.state.year != 0) {
var fecha = Date.parse(this.state.year + '-' + this.state.month + '-' + this.state.day);
var hoy = new Date();
var fechaNacimiento = new Date(fecha);
var edad_ahora = hoy.getFullYear() - fechaNacimiento.getFullYear();
var mes = hoy.getMonth() - fechaNacimiento.getMonth();
if (mes < 0 || (mes === 0 && hoy.getDate() < fechaNacimiento.getDate())) {
edad_ahora--;
}
this.setState({ edad: edad_ahora });
} else {
Alert.alert(
'Error',
'Por favor introduce una fecha valida',
[
{ text: 'Ok' }
],
{ cancelable: false },
);
}
}
render () {
return (
<KeyboardAwareScrollView contentContainerStyle={styles.container} scrollEnabled enableOnAndroid={true}
resetScrollToCoords={{x:0, y:0}}>
<View style={styles.topView}>
// This is the button I press to go back to the first screen
<TouchableOpacity style={styles.img} onPress={() => this.props.navigator.navigate('Home')}>
<Image source={flecha} />
</TouchableOpacity>
<View style={styles.topTextWrapper}>
<Text style={styles.topTextPrimary}>Bienvenido a Neuron</Text>
<Text style={styles.topTextSecondary}>¿O no?</Text>
</View>
</View>
<View style={styles.middleView}>
<Text style={styles.formText}>Fecha de nacimiento</Text>
<View style={styles.formRow}>
<View style={styles.textInputWrapper}>
<TextInput style={styles.formInput} placeholder='DD' keyboardType='number-pad'
onChangeText={ value => this.setState({ day: value }) }/>
</View>
<View style={styles.textInputWrapper}>
<TextInput style={styles.formInput} placeholder='MM' keyboardType='number-pad'
onChangeText={ value => this.setState({ month: value }) }/>
</View>
<View style={styles.textInputWrapper}>
<TextInput style={styles.formInput} placeholder='AA' keyboardType='number-pad'
onChangeText={ value => this.setState({ year: value }) }/>
</View>
</View>
</View>
<View style={styles.buttonView}>
<TouchableOpacity style={styles.button} onPress={this._ageCalc}>
<Text style={styles.buttonText}>CALCULAR EDAD</Text>
</TouchableOpacity>
</View>
<View style={styles.ageView}>
<Text style={styles.ageTextPrimary}>Tu edad es:</Text>
<Text style={styles.ageNumber}>{this.state.edad}</Text>
<Text style={styles.ageTextSecondary}>Años</Text>
</View>
</KeyboardAwareScrollView>
);
}
}
export default App; // AgeInput
Thanks for your help

You can do something like this...
render () {
const { navigate } = props.navigation;
//function to go to next screen
goToNextScreen = () => {
return navigate('Home');
return (
<KeyboardAwareScrollView contentContainerStyle={styles.container} scrollEnabled enableOnAndroid={true}
resetScrollToCoords={{x:0, y:0}}>
<View style={styles.topView}>
// This is the button I press to go back to the first screen
<TouchableOpacity style={styles.img} onPress={() => this.goToNextScreen()}>
<Image source={flecha} />
</TouchableOpacity>
<View style={styles.topTextWrapper}>
<Text style={styles.topTextPrimary}>Bienvenido a Neuron</Text>
<Text style={styles.topTextSecondary}>¿O no?</Text>
</View>
</View>
<View style={styles.middleView}>
<Text style={styles.formText}>Fecha de nacimiento</Text>
<View style={styles.formRow}>
<View style={styles.textInputWrapper}>
<TextInput style={styles.formInput} placeholder='DD' keyboardType='number-pad'
onChangeText={ value => this.setState({ day: value }) }/>
</View>
<View style={styles.textInputWrapper}>
<TextInput style={styles.formInput} placeholder='MM' keyboardType='number-pad'
onChangeText={ value => this.setState({ month: value }) }/>
</View>
<View style={styles.textInputWrapper}>
<TextInput style={styles.formInput} placeholder='AA' keyboardType='number-pad'
onChangeText={ value => this.setState({ year: value }) }/>
</View>
</View>
</View>
<View style={styles.buttonView}>
<TouchableOpacity style={styles.button} onPress={this._ageCalc}>
<Text style={styles.buttonText}>CALCULAR EDAD</Text>
</TouchableOpacity>
</View>
<View style={styles.ageView}>
<Text style={styles.ageTextPrimary}>Tu edad es:</Text>
<Text style={styles.ageNumber}>{this.state.edad}</Text>
<Text style={styles.ageTextSecondary}>Años</Text>
</View>
</KeyboardAwareScrollView>
);
}
}
export default App;

Just replace this :
// This is the button I press to go back to the first screen
<TouchableOpacity style={styles.img} onPress={() => this.props.navigator.navigate('Home')}>
with
// This is the button I press to go back to the first screen
<TouchableOpacity style={styles.img} onPress={() => this.props.navigation.navigate('Home')}>
Hope it help.s

Related

TouchOpacity onPress request is not working with formik and react-native-text-input-mask

When i tried to login the button is not sending request. On button pree i supposed to console the output. It seems that the onChangeText and onChange is not working correcttly in TextInputMask.
TouchableOpacity tag has onPress event where onPress={()=>formikProps.handleSubmit()} is not triggering the onSubmit props of formik.
Here i'm using yup for validation and Formik for submitting data.
const validationSchema = yup.object().shape({
phoneNumber: yup
.string()
.label("Phone Number")
.required("Phone Number is required."),
password: yup.string().label("Password").required("Password is required."),
});
class Home extends Component {
constructor(props) {
super(props);
this.state = {
username: "",
password: "",
press: false,
ButtonStateHolder: false,
};
}
render() {
return (
<ImageBackground style={{ width: "100%", height: "100%" }} source={bgImg}>
<ScrollView>
<Formik
initialValues={{ phoneNumber: "", password: "" }}
onSubmit={(values, actions) => {
this.setState({
password: values.password,
ButtonStateHolder: true,
});
console.warn(this.state.phoneNumber);
console.warn(this.state.password);
}}
validationSchema={validationSchema}
>
{(formikProps) => (
<React.Fragment>
<View>
<View>
<Text>Phone number</Text>
<TextInputMask
keyboardType="number-pad"
ref={(ref) => (this.phoneField = ref)}
onChangeText={(formatted, extracted) => {
this.setState({
phoneNumber: extracted,
});
}}
onChange={formikProps.handleChange("phoneNumber")}
onBlur={formikProps.handleBlur("phoneNumber")}
placeholder={""}
mask={"([000]) [000] [0000]"}
/>
<Text style={styles.errMsg}>
{formikProps.touched.phoneNumber &&
formikProps.errors.phoneNumber}
</Text>
</View>
<View>
<Text style={styles.formLable}>Password</Text>
<TextInput
onChangeText={formikProps.handleChange("password")}
onBlur={formikProps.handleBlur("password")}
placeholder={""}
returnKeyType={"done"}
autoCapitalize={"none"}
autoCorrect={false}
/>
<Text style={styles.errMsg}>
{formikProps.touched.password &&
formikProps.errors.password}
</Text>
<TouchableOpacity
activeOpacity={0.7}
style={styles.btnEye}
onPress={this.showPass}
>
<Image source={eyeImg} style={styles.iconEye} />
</TouchableOpacity>
</View>
</View>
<View style={styles.loginBottom}>
<TouchableOpacity
style={styles.button}
onPress={() => formikProps.handleSubmit()}
>
<Text style={styles.buttonText}> Login </Text>
</TouchableOpacity>
</View>
</React.Fragment>
)}
</Formik>
</ScrollView>
</ImageBackground>
);
}
}
export default Home;
onPress console log is not printed
Someone please help to solve this issue
Formik will manage the state of inputs for you so you don't need to declare it.
const validationSchema = yup.object().shape({
phoneNumber: yup
.string()
.label("Phone Number")
.required("Phone Number is required."),
password: yup.string().label("Password").required("Password is required."),
});
class Home extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<ScrollView>
<Formik
initialValues={{ phoneNumber: "", password: "" }}
onSubmit={(values, actions) => {
alert(JSON.stringify(values));
}}
validationSchema={validationSchema}
>
{({handleChange, values, handleSubmit, touched, errors, handleBlur}) => (
<React.Fragment>
<View>
<View>
<Text>Phone number</Text>
<TextInput
keyboardType="number-pad"
onChangeText={handleChange}
onChange={handleChange("phoneNumber")}
onBlur={handleBlur("phoneNumber")}
placeholder={""}
mask={"([000]) [000] [0000]"}
value={values.phoneNumber}
/>
<Text>
{touched.phoneNumber &&
errors.phoneNumber}
</Text>
</View>
<View>
<Text>Password</Text>
<TextInput
onChangeText={handleChange("password")}
onBlur={handleBlur("password")}
placeholder={""}
returnKeyType={"done"}
autoCapitalize={"none"}
autoCorrect={false}
value={values.password}
/>
<Text>
{touched.password &&
errors.password}
</Text>
</View>
</View>
<View >
<TouchableOpacity
onPress={() => handleSubmit()}
>
<Text> Login </Text>
</TouchableOpacity>
</View>
</React.Fragment>
)}
</Formik>
</ScrollView>
</View>
);
}
}
You can also manage the form with the useFormik hook instead of the Formik component
import { useFormik } from 'formik';
const validationSchema = yup.object().shape({
phoneNumber: yup
.string()
.label("Phone Number")
.required("Phone Number is required."),
password: yup.string().label("Password").required("Password is required."),
});
const Home = () => {
const { handleChange, values, handleSubmit, touched, errors, handleBlur } = useFormik({
initialValues: {
phoneNumber: "", password: ""
},
onSubmit: (values, actions) => {
alert(JSON.stringify(values));
},
validationSchema
});
console.log(values);
return (
<View>
<ScrollView>
<View>
<View>
<Text>Phone number</Text>
<TextInput
keyboardType="number-pad"
onChangeText={handleChange}
onChange={handleChange("phoneNumber")}
onBlur={handleBlur("phoneNumber")}
placeholder={""}
mask={"([000]) [000] [0000]"}
value={values.phoneNumber}
/>
<Text>
{touched.phoneNumber &&
errors.phoneNumber}
</Text>
</View>
<View>
<Text>Password</Text>
<TextInput
onChangeText={handleChange("password")}
onBlur={handleBlur("password")}
placeholder={""}
returnKeyType={"done"}
autoCapitalize={"none"}
autoCorrect={false}
value={values.password}
/>
<Text>
{touched.password &&
errors.password}
</Text>
</View>
</View>
<View >
<TouchableOpacity
onPress={() => handleSubmit()}
>
<Text> Login </Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
);
}
}
Let me know if I misunderstood something or if it helps you

react-native-camera freeze when back on screen

I'm developing an application for a school project, and in this application I have a camera component in each view. When I go back on a view the camera freeze.
There is my code of one view:
class LoginView extends React.Component {
constructor(props) {
super(props);
}
togglePseudo = pseudo => {
const action = {type: 'USER_PSEUDO', value: pseudo};
this.props.dispatch(action);
};
render() {
const {navigate} = this.props.navigation;
const userPseudo = this.props.userPseudo;
return (
<View style={style.mainContainer}>
<RNCamera
style={style.backgroundCamera}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.on}
androidCameraPermissionOptions={{
title: "Permission d'utiliser la camera",
message: "L'application necessite l'autorisation de la camera",
buttonPositive: 'Autoriser',
buttonNegative: 'Refuser',
}}
/>
<View style={style.goContainer}>
<TouchableOpacity
style={style.backButton}
onPress={() => navigate('HomeView')}>
<Image source={require('assets/images/back-button.png')} />
</TouchableOpacity>
<View style={style.centeredElements}>
<Text style={style.titleMission}>Mission "Pc"</Text>
<View style={style.modalChoosePseudo}>
<Text style={style.modaltitle}>Choisir un pseudo</Text>
<TextInput
style={style.pseudoInput}
onChangeText={pseudo => this.togglePseudo(pseudo)}
value={userPseudo}
/>
{userPseudo !== '' ? (
<TouchableOpacity
style={style.validateButton}
onPress={() => navigate('InGame')}>
<Text style={style.buttonText}>Valider</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
style={[style.validateButton, style.validateButtonDisabled]}
onPress={() =>
Alert.alert('Alerte', 'Veuillez entrer un pseudo')
}>
<Text
style={[style.buttonText, style.validateButtonDisabled]}>
Valider
</Text>
</TouchableOpacity>
)}
</View>
<Image
style={style.logoDimagine}
source={require('assets/images/logo_title_vertical.png')}
/>
</View>
</View>
</View>
);
}
}
I have already looked for solutions, so I tried what I found.
I've try to use componentDidMount with willFocus and willBlur, but it never detect them :
componentDidMount() {
const {navigation} = this.props;
navigation.addListener('willFocus', () =>
this.setState({focusedScreen: true}),
);
navigation.addListener('willBlur', () =>
this.setState({focusedScreen: false}),
);
}

Navigating to another screen after user authentication

I have a login app some users in a Firebase database. When a user logs in into their account succesfully, I want to redirect them to another screen I have. Unfortunately, every single approach I've tried since a couple of days does not work as intended.
This is my code, I'm omitting the StyleSheet and the libraries (and yes, I have my other screen imported into the App.js)
class HomeScreen extends Component {
state = { username: null, password: null, nonValidInput: null }
_onSubmit = ({ navigation }) =>{
const { navigate } = this.props.navigation;
if(EmailValidator.validate(this.state.username) == true) {
this.setState({ nonValidInput: false });
const { username, password } = this.state;
try {
firebase.auth().signInWithEmailAndPassword(this.state.username, this.state.password).then(navigator.navigate('Age'));
} catch {
Alert.alert(
'Error',
'Los datos no son correctos',
[
{ text: 'Ok' }
],
{ cancelable: false }
);
}
} else {
this.setState({ nonValidInput: true });
}
}
render() {
return (
<KeyboardAwareScrollView contentContainerStyle={styles.container} scrollEnabled
enableOnAndroid={true} resetScrollToCoords={{x:0, y:0}}>
<View style={styles.logo}>
<Image source = {logo} style={styles.img}/>
<Text style={styles.textLogoPrimary}>Neuron App</Text>
<Text style={styles.textLogoSecondary}>Test</Text>
</View>
<View style={styles.formElement}>
<Text style={styles.formText}>Correo Electrónico</Text>
<TextInput keyboardType='email-address' placeholder='Email' onChangeText={value => this.setState({ username: value })}
style={styles.formInput} />
{this.state.nonValidInput ? (
<Text style={styles.textAlert}>Correo electrónico no valido.</Text>
) : null}
</View>
<View style={styles.formElement}>
<Text style={styles.formText}>Contraseña</Text>
<TextInput style={styles.formInput} placeholder='Contraseña' onChangeText={value => this.setState({ password: value })}
secureTextEntry={true}/>
</View>
<View style={styles.buttonView}>
<TouchableOpacity style={styles.button} onPress={this._onSubmit}>
<Text style={styles.buttonText}>Iniciar</Text>
</TouchableOpacity>
</View>
</KeyboardAwareScrollView>
);
}
}
const Stack = createStackNavigator();
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}} initialRouteName="Home">
<Stack.Screen name='Home' component={HomeScreen} />
<Stack.Screen name='Age' component={AgeInput} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
Thanks for your help
What is navigator? You can use navigate from navigation prop directly:
firebase.auth().signInWithEmailAndPassword(this.state.username, this.state.password).then(() => this.props.navigation.navigate('Age'));
Also, make sure you call the function in the then clause in the right way.

Call function on another file JS React Native

I have a Parent Class and Child Class but however i can't call a function on Parent Class from Child Class
It just for close the Modal and send a few data from Sorting on my modal. Sorry im a newbie on RN
On OrderScreen i want to separate a modal and screen, so i call modal on another file JS, then on ModalSort.js i want to call back that function has been on his Parents or Order.screen.js
so many way i try but that modal still can't close, if i put onBackdropPress={() => ()} the modal can be close but no respon that i got
Order.screen.js (a.k.a Parents.js)
class OrderScreen extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
};
};
exit = () => this.setState({ visibleModal: false });
_applySort = () => {
this.setState({ visibleModal: false });
this.onRefresh();
};
pressSort = () => this.setState({ visibleModal: 4 });
render() {
return (
<View style={styles.containerTop}>
<Modal isVisible={this.state.visibleModal === 5} style={styles.bottomModal}>
{this._renderModal()}
</Modal>
<Modal isVisible={this.state.visibleModal === 4}
style={styles.bottomModal} onBackdropPress={() => {this.toggleModal();}}>
{this._renderModalSort()}
</Modal>
<Modal isVisible={this.state.visibleModal === 3} style={styles.bottomModal}>
{this._renderModalFilter()}
</Modal>
<Modal isVisible={this.state.visibleModal === 2} style={styles.bottomModal}>
{this._renderModalEmail()}
</Modal>
<NavigationEvents
onWillFocus={this.willFocusAction} />
<GeneralStatusBarColor backgroundColor="#FFF" barStyle="light-content" />
</View>
)
};
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit.bind(this);
}}
/>
)
};
const mapStateToProps = ({ authOrder }) => {
const { orderSummary, error, loading, loadingSummary, loadingEmail, typeOfLocation, openNext, openList, closedList, closedNext } = authOrder;
return { orderSummary, error, loading, loadingSummary, loadingEmail, typeOfLocation, openNext, openList, closedList, closedNext };
};
export default connect(mapStateToProps, { getOrderSummary, getOpenOrderList, getClosedOrderList, sendEmailCsvAllOrder, logoutSession })(OrderScreen);
ModalSort.js (a.k.a Child.js)
class ModalSort extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
}
};
sorter = (isi) => this.setState({ sorted: isi });
_applySort = () => {
this.setState({ visibleModal: false });
// this.onRefresh();
};
render() {
return(
<View style={styles.modalContentSort}>
<View style={styles.modalCenter}>
<View style={styles.headerModel}>
<View style={styles.headerBack}>
<TouchableOpacity onPress={()=>{this.props.exit()}}>
{/* <NavigationEvents onWillFocus={this.willFocusAction} /> */}
<Image style={styles.logoClose} source={require('../../assets/icons/iconClose.png')} />
</TouchableOpacity>
</View>
<View style={styles.headerSort}>
<Text style={styles.textFilter}>Sort by</Text>
</View>
</View>
<Text style={styles.textFilter}>SO Number</Text>
<View style={styles.headerModel}>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(1)}>
<Text style={this.state.sorted == 1 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberAscending.png')} />Ascending</Text>
</TouchableOpacity>
</View>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(2)}>
<Text style={this.state.sorted == 2 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberDescending.png')} />Descending</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.textFilter}>PO Customer</Text>
<View style={styles.headerModel}>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(3)}>
<Text style={this.state.sorted == 3 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberAscending.png')} />Ascending</Text>
</TouchableOpacity>
</View>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(4)}>
<Text style={this.state.sorted == 4 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberDescending.png')} />Descending</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.textFilter}>SO Date</Text>
<View style={styles.headerModel}>
<TouchableOpacity onPress={() => this.sorter(6)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 6 ? styles.headerBorderItemActive : styles.headerBorderItem}>Newest</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.sorter(5)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 5 ? styles.headerBorderItemActive : styles.headerBorderItem}>Oldest</Text>
</View>
</TouchableOpacity>
</View>
<Text style={styles.textFilter}>ETA</Text>
<View style={styles.headerModel}>
<TouchableOpacity onPress={() => this.sorter(8)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 8 ? styles.headerBorderItemActive : styles.headerBorderItem}>Newest</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.sorter(7)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 7 ? styles.headerBorderItemActive : styles.headerBorderItem}>Oldest</Text>
</View>
</TouchableOpacity>
</View>
<TouchableHighlight style={styles.buttonSort} onPress={this._applySort.bind(this)} >
<Text style={styles.textApply}>Apply</Text>
</TouchableHighlight>
</View>
</View>
)
};
}
export default ModalSort;
Close modal in Parent component from Child component:
Your Order.screen.js has a mistake that make your program wouldn't run properly. When you use this.exit.bind(this);, it will return a callback, not a function. So, when you call this.props.exit() in ModalSort.js, it will call exit that actually shows nothing. To resolve this, you have 2 ways:
Order.screen.js
_renderModalSort = () => {
return (
<ModalSort
exit={this.exit.bind(this)}
/>
)
};
or
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit();
}}
/>
)
};
Send data from sorting modal:
Since you're using Redux, I suggest you create 2 actions. First action is to save your data to your state tree. Second one is to get those data. If you're not good at Redux, or you don't want to use it, you can try these step:
Initialize a variable to hold your data in Parent:
class OrderScreen extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
};
this.data = null; // Your data goes here.
/*
You can store your data in state if you want to re-render when updating your data.
this.state = {
visibleModal: null,
data: null
}
*/
}
}
Create a function that save your data in Parent:
saveData(data) {
this.data = data;
}
Pass that function to Child:
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit();
}}
saveData={(data) => {
this.saveData(data);
}}
/>
)
};
Lastly, you can call it from Child:
class ModalSort extends Component {
sorting() {
data = null; // Your data will be stored in this variable
// You sorting function goes here
this.props.saveData(data); // Save your data
}
}
In case you have other works to do with saved data, you can modify the saveData(data) function in Parent.
Hope this will help you!

state disappears when method is call

I'm working on a class project and my state is disappearing. After componentDidMount console.log(this.state) is fine. I initiate setInterval and call inc(). Somehow when I enter inc() the state gets wiped out.
import React from 'react';
import { TextInput,Button,StyleSheet, Text, View } from 'react-native';
import styles from './styles/styles.js';
debug=true
export default class App extends React.Component {
constructor(){
super()
this.state={timer:'WORK',
workTime: 25*60+0,
breakTime: 5*60+0,
currentTime:0,
remainingTime:null,
min:0,
sec:0,
startFlag:false,
resetFlag:false}
}
componentDidMount(){
this.interval=setInterval(this.inc,10000)
if(debug)console.log('COMPONENTDIDMOUNT',this.state)
}
static getDerivedStateFromProps(nextProps, prevState) {
if(debug)console.log('GETDERIVEDSTATEFROMPROPS',prevState)
return null
}
shouldComponentUpdate(nextProps,nextState){
if(debug)console.log('SHOULDCOMPONENTUPDATE',nextState)
return true
}
componentDidUpdate(){
if(debug)console.log('COMPONENTDIDUPDATE',this.state)
}
componentWillUnmount(){
if(debug)console.log('COMMPONENTWILLUNMOUNT',this.state)
}
startToggle(){
if(endTime === null)this.setState({remainingTime:this.state.workTime,
startFlag:!this.state.startToggle})
else this.setState({remainingTime:!this.state.startFlag})
}
textTime(){
let min = Math.floor(this.state.remainingTime / 60).toString()
let sec = (this.state.remainingTime % 60)
if (sec < 10)sec ? '0' + sec : sec.toString()
this.setState({min:min,sec:sec})
}
inc(){
console.log(this.state)
}
captureInput(){}
render() {
console.log('RENDER',this.state)
return (
<View style={styles.container}>
<Text style={styles.bigFont}>{`${this.state.timer + 'TIMER'}`}</Text>
<Text style={styles.bigFont}>12:00</Text>
<View style={styles.button}>
<Button title='START' onPress={()=>this.startToggle()} />
<Button title='RESET' onPress={()=>this.resetToggle()} />
</View>
<View style={styles.row}>
<Text style={[styles.bold,{marginRight:10},{width:112},
{textAlign:'right'}]}>
'Work Timer:'</Text>
<Text style={styles.bold}> min:</Text>
<TextInput
defaultValue='50'
style={styles.input}
onChangeText={(text) => {this.captureInput(text)}}
/>
<Text style={styles.bold}> sec:</Text>
<TextInput
defaultValue='50'
style={styles.input}
onChangeText={(text) => {this.captureInput(text)}}
/>
</View>
<View style={styles.row}>
<Text style={[styles.bold,{marginRight:10},{width:112},
{textAlign:'right'}]}>
'Break Timer:'</Text>
<Text style={styles.bold}> min:</Text>
<TextInput
defaultValue='50'
style={styles.input}
onChangeText={(text) => {this.captureInput(text)}}
/>
<Text style={styles.bold}> sec:</Text>
<TextInput
defaultValue='50'
style={styles.input}
onChangeText={(text) => {this.captureInput(text)}}
/>
</View>
</View>
)
}
}
You have 2 options:
Change inc() to inc = () =>
or
Change this.inc to this.inc.bind(this)
Change your inc method declaration to
inc = () => {
...
}
As per your code, this inside inc() is not referring to the component, hence you are not getting state either.
Hope this will help!