componentWillMount doesn't get called again when navigating back to my original component - react-native

screen A: calling componentWillMount successfully and then navigating to screen B,
screen B: do some redux changes (that will affect the data in WillMount) and then navigating back to A but componentWillMount doesn't get called and preventing desirable data from appearing on the screen
screen A:
componentWillMount(){
this.props.fetchData();
console.log('fetched')
}
renderItem({item}){
return <Text>{item.name}</Text>
}
render(){
const array = Object.values(this.props.data)
return(
<View style={{flex: 1}}>
<Inline>
<View style={styles.container}>
<View style={styles.headerContainer}>
<Header style={styles.header} HeaderText={'EmployeeList'}
/>
</View>
<TouchableOpacity style={styles.buttonContainer}
onPress={()=> this.props.navigation.navigate('CreateEmp')}
//screen B
>
<Text style={styles.buttonStyle}>Add an Employee</Text>
</TouchableOpacity>
</View>
</Inline>
<FlatList
data={array}
renderItem={this.renderItem}
keyExtractor={array1 => array1.name}
/>
</View>
screen B:
functionOne(){
const {name, phone, createEmployee, shift} = this.props
createEmployee(name, phone, shift)
}
functionTwo(){
this.props.navigation.navigate('EmployeeList')//screen A
}
functionCombined(){
this.functionOne();
this.functionTwo();
}
and calling functionCombined in the class of course

The componentWillMount is executed when the screen is rendered.
However, when navigating to the Navigate command, if the screen is first moved, it is rendered to draw the screen, but if it is already rendered, it is not rendered again.
The function shall be moved using a push commands to run again.
functionTwo(){
this.props.navigation.push('EmployeeList')//screen A
}

Related

React Native: Disable animations when onPress function is called inside Animated.View

I have a animated view stack which contains a Pressable component to navigate to another screen. But when I press the button, navigation happens after the animation of the container. I want to make it instant.
<Animated.View>
<Animated.View style={[styles.headerContainer, titleStyle]}>
<Animated.Text style={styles.verificationTitle}>
{activationBoxTitle}
</Animated.Text>
<ArrowRightWhite />
</Animated.View>
<Animated.View style={[styles.container, descriptionContainerStyle]}>
<ImageBackground
style={styles.backgroundImage}
resizeMode="cover"
source={images.activateAccBackground}
>
<Pressable
onPress={() => navigation.navigate(
"GeneralQuestions", {
screen: navigateActivationToPage
})}
>
<Animated.Text style={descriptionStyle}>
{activationBoxDescription}
</Animated.Text>
</Pressable>
</ImageBackground>
</Animated.View>
</Animated.View>
How can I do that?
I've seen a problem like this in a question here and I've also seen it in a project. The most common is before navigation, add a setTimeOut, this will cause a delay and have the animation and navigation. It would look something like this:
function handleNavigate() {
setTimeout(() => {
navigation.navigate('GeneralQuestions', {
screen: navigateActivationToPage,
});
}, 5000);
}
// ...
<Pressable
onPress={() => handleNavigate}
/>
Then at setTimeOut time, you add a value that makes sense according to your animation

Retrieve data from screen to screen in react native

Im sending the data "item.email" from screen X to screen HomeParent
How can I retrieve the data in the HomeParent screen?
renderItem=(item,index)=>{
return(
<View style={styles.listItemContainer}>
<TouchableOpacity onPress={()=>this.props.navigation.navigate("HomeParent",item.email)}>
<View style={styles.listItemTitleContainer}>
<Text>Hello</Text>
</View>
</TouchableOpacity>
</View>
)
}
Pass it as a object field
<TouchableOpacity onPress={()=>this.props.navigation.navigate("HomeParent",{mail:item.email})}>
and use getParam like this,
const email = this.props.navigation.getParam('mail')

Present modal inside a screen

I'm creating an application where I'm using a MaterialBottomTabBar and in the Home Screen I've a button which are supposed to open up a <Modal>.
After investigating this for quite some time I found out that I cannot present the modal when using the tabbar. I've tried to put the modal in all my tabbar-screens (without any success). And then moved the modal over to another screen which are not included in the tab-bar and the modal worked perfectly fine.
export default function Home({ route, navigation }){
const [modal, setModal] = useState(false)
return(
<View style={styles.container}>
<Modal visible={modal} transparent={true}>
<View style={{height: "100%", width: "80%", backgroundColor: "blue"}}>
<Text>TIFMNASIFAMNFISAMFIAOFMSAOFMAFOPSAMF</Text>
</View>
</Modal>
<TouchableOpacity style={styles.addNewButton} onPress={() => setModal(true)}>
<Text style={styles.addNewButtonText}>+</Text>
</TouchableOpacity>
</View>
)
}
As you can see i'm using the React Native Hooks useState(false) and refers to it inside the Modal. But whenever I tap the <TouchableOpacity> the modal is not being presented.
NOTE!
The modal is being presented if I replace the
<Modal visible={modal} transparent={true}>
to
<Modal visible={true} transparent={true}>
But would be runned instantly, which is not an option in my case.
Do you have any idea how I can run this modal inside the screen?

White flash after Splash Screen on Android React Native

I have a React Native App built with ExpoKit SDK 32. I have a main switch navigator (from React Navigation) which starts with a Loading Screen, there I do some business logic to decide what screen should load next (Screen A or B), on the next screen I disable the Splash Screen.
The problem is: Whenever I move from the Loading Screen to screen A, I get a White flash.
I have not seem it happen on iOS, only on Android.
Screen A has a imageBackground Component on the whole screen. The image is cached and its the same as the splash screen.
I've tried rendering an image equal to the SplashScreen on the background of the Loading Screen. Same result.
Then I put on my componentDidMount of Screen A SplashScren.hide(). Same result.
The best outcome as been putting 'SplashScreen.hide()' on the onLoadEnd of my background Image of Screen A.
Any help is appreciated! Is there a better way to deal with this kind of situation involving the Switch Component on React Navigation?
This is how my Screen A looks now:
async imageLoaded() {
SplashScreen.hide();
try {
const usuario = await SecureStore.getItemAsync(LOGIN_USUARIO_LOCAL_AUTH);
if (usuario) {
await this.localAuth();
}
} catch (err) {
// faz nada
}
}
....
render() {
const { usuario, senha } = this.state;
const { logando, localAuthHardware } = this.props;
const labelHardware = localAuthLabel(localAuthHardware);
return (
<SafeAreaView style={styles.safeArea}>
<ImageBackground
source={require('../../../assets/images/start.png')}
resizeMode="cover"
style={styles.container}
imageStyle={styles.container}
onLoadEnd={this.imageLoaded}
fadeDuration={0}
>
<KeyboardAwareScrollView alwaysBounceVertical={false} keyboardShouldPersistTaps="handled">
<Image
source={require('../../../assets/images/baladapp-icone.png')}
style={styles.baladappicone}
resizeMode="contain"
fadeDuration={0}
/>
<View style={styles.baladappView}>
<Image
source={require('../../../assets/images/BaladAPP.png')}
resizeMode="contain"
style={styles.baladapp}
fadeDuration={0}
/>
<Text style={styles.produtorText}>PRODUTOR</Text>
</View>
<View style={styles.formView}>
<TextInput
placeholder="Usuário"
style={[styles.input, { elevation: 1.3 }]}
underlineColorAndroid="transparent"
value={usuario}
onChangeText={this.changeUsuario}
keyboardType={Platform.OS === 'ios' ? 'email-address' : 'visible-password'}
autoCorrect={false}
autoCapitalize="none"
/>
<PasswordInputField
placeholder="Senha"
style={styles.input}
enablesReturnKeyAutomatically
underlineColorAndroid="transparent"
value={senha}
onChangeText={this.changeSenha}
containerStyle={[styles.containerPasswordStyle, { elevation: 1.3 }]}
onSubmitEditing={this.login}
/>
<TouchableOpacity
onPress={this.abrirRecuperarSenha}
style={styles.esqueceuTextView}
hitSlop={hitSlop15}
>
<Text style={styles.esqueceuText}>Esqueceu a senha?</Text>
</TouchableOpacity>
<Button
text="ACESSAR SISTEMA"
containerStyle={styles.button}
textStyle={styles.buttonText}
onPress={this.login}
loading={logando}
loadingColor={colors.branco}
/>
{localAuthHardware.length > 0 && (
<TouchableOpacity
onPress={this.localAuth}
style={styles.localAuthView}
hitSlop={hitSlop15}
>
<Text style={styles.esqueceuText}>{`Acessar com ${labelHardware}`}</Text>
</TouchableOpacity>
)}
</View>
</KeyboardAwareScrollView>
</ImageBackground>
</SafeAreaView>
);
}

How to handle a touch gesture by multiple components in react native?

Using React Native 0.47 and yarn, I'm creating an introduction section in which you can swipe through multiple pages and finally get to the home page.
So we swipe pages from right to left and move like this: Slide1 -> Slide2 -> Slide3 -> Slide4 -> Home . I have a component that displays a slide page which covers all of the screen. For example, first slide looks like this:
And the code for that is :
class IntroSlide extends Component {
render () {
return (
<View style={[styles.introSlide, this.props.myStyle]}>
<View style={styles.introSlideIconView}>
<Icon name={this.props.iconName} size={SLIDE_ICON_SIZE} color="white"/>
</View>
<View style={styles.introSlideTextView}>
<Text style={styles.introSlideTextHeader}> {this.props.headerText} </Text>
<Text style={styles.introSlideText}> {this.props.text} </Text>
</View>
</View>
);
}
}
And i use it that here:
import AppIntro from 'react-native-app-intro';
// Other imports here
export default class Intro extends Component {
render() {
return (
<View style={{flex: 1}}>
<AppIntro
showSkipButton={false}
nextBtnLabel={<Text style={styles.introButton}>بعدی</Text>}
doneBtnLabel={<Text style={styles.introButton}>شروع</Text>}
>
<IntroSlide
iconName="user"
myStyle={styles.introSlide1}
headerText="DontCare"
text= "SomeTextDoesntMatter"
/>
</AppIntro>
</View>
);
}
}
I'm using react-native-app-intro for this which provides me a very cool swiper but here's the problem:
I have a small View component with an Icon (react-native-vector-icons) in it as you can see that i want to rotate as i swipe to the next page. I created a panResponder in IntroSlide and set it to top View of it. but my slide can't receive any events. i think some parent views provided by react-native-app-intro captures all the events and i can still swipe through pages but no console log appears. here's what i did:
class IntroSlide extends Component {
constructor(props) {
super(props);
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: () => console.log("Moving"),
});
this.pan = panResponder;
}
render () {
return (
<View
style={[styles.introSlide, this.props.myStyle]}
{...this.pan.panHandlers}
>
<View style={styles.introSlideIconView}>
<Icon name={this.props.iconName} size={SLIDE_ICON_SIZE} color="white"/>
</View>
<View style={styles.introSlideTextView}>
<Text style={styles.introSlideTextHeader}> {this.props.headerText} </Text>
<Text style={styles.introSlideText}> {this.props.text} </Text>
</View>
</View>
);
}
}
I did the same to the View component with flex: 1 and i had different result. i get console logs as expected but i can't swipe anymore. So how can i swipe through pages while receiving touch events in parent component ? (In other words, i want two different components to receive touch events, and I'm developing for android)