Difference calling function inside onPress{} - react-native

What's de difference between calling a function like this:
<TouchableOpacity onPress{function()}> </TouchableOpacity>
Or call it like
<TouchableOpacity onPress{() => function()}> </TouchableOpacity>

In the following line, as soon as the component is rendered, the function() will get called, which is not the proper way. If you want to run a function like that, then make use of the useEffect hook.
<TouchableOpacity onPress{function()}> </TouchableOpacity>
On the other hand in the following case, the following() will only get executed once the TouchableOpacity component is pressed.
<TouchableOpacity onPress{() => function()}> </TouchableOpacity>

Related

Why does TouchableOpacity automatically trigger onPress in ReactNative Expo Snack?

I have a small ReactNative app in Expo Snack that includes a single components with a TouchableOpacity.
export default function AssetExample() {
function clicked() {
alert('clicked')
}
return (
<View style={styles.container}>
<TouchableOpacity onPress={clicked()}>
<Text style={styles.paragraph}>
Click the icon
</Text>
<Image style={styles.logo} source={require('../assets/snack-icon.png')} />
</TouchableOpacity>
</View>
);
}
Every time the app is started the alert is shown, meaning TouchableOpacity triggers onPress. Why? And how can I circumvent this?
You should pass the reference of your function to TouchableOpacity like this
<TouchableOpacity onPress={clicked}>
</TouchableOpacity>
or pass it with arrow function
<TouchableOpacity onPress={()=> clicked()}>
</TouchableOpacity>
so it will be called inside TouchableOpacity component whenever required (button click), otherwise it will be called only one time during render phase.
See these docs for handling events in React https://reactjs.org/docs/handling-events.html

why does this one event handler work but the other one fails?

Can you explain the technical difference between the 2 following implementations and why one breaks and the other one works? Here's the target function:
loginWithEmail(){
this.props.navigation.navigate('LoginWithEmail');
}
The following onPress implementation will successfully call the loginWithEmail() function, but the following error is thrown within the loginWithEmail() function:
"this.props.navigation is undefined"
<View>
<TouchableOpacity onPress={this.loginWithEmail}>
<Text>
Log in with Email
</Text>
</TouchableOpacity>
</View>
However, if I wire up the onPress event handler function with an arrow function format like the following example, the loginWithEmail() function executes successfully without error:
<View>
<TouchableOpacity onPress={() => this.loginWithEmail()}>
<Text>
Log in with Email
</Text>
</TouchableOpacity>
</View>
Can you explain the technical difference between the 2 following implementations and why one breaks and the other one works? Does this have something to do with "closures"?

How can I set onPress event in a child component?

I have a file called SplashScreen.js with a StackNavigator. Sample code:
Inside my SplashScreen.js I have a component called "Login" and INSIDE Login I have a component called "TouchbleOpacity"
What I need is to change the "onPress" event of my TouchbleOpacity component. So I'll be able to navigate in my Navigator (that are inside my SplashScreen.js). The onPress event should look similar to this: onPress={() => navigation.navigate('TelaCadastrar01')
If there is a better way to change the onPress event of my TouchbleOpacity, please tell me, thanks!
I don't know if this is what you are looking for, but i'll give it a try:
In your Login Component you do:
//first button
<TouchableOpacity onPress={this.props.onPress} >
<Text> ... </Text>
</TouchableOpacity>
//second button
<TouchableOpacity onPress={this.props.onPressButton2} >
<Text> ... </Text>
</TouchableOpacity>
Now you are able to pass any onPress function to your Login Component. e.g.
<Login onPress={() => navigation.navigate('TelaCadastrar01')} onPressButton2={() => console.log('second scene')}/>

onPress in TouchableOpacity doesn't trigger

I need your help! My goal is to change the style of my button after I clicked it! I heard about direct manipulation and I decided to give it a try. Now I don't know why but the onPress inside my TouchableOpacity doesn't work. Here is the code:
<TouchableOpacity onPress={() => this.changeStyle}>
<TouchableHighlight style={styles.answer} ref="answer1">
<Text ...> Some Text </Text>
</TouchableHighlight>
</TouchableOpacity>
And here is my changeStyle function:
changeStyle() {
this.refs['answer1'].setNativeProps({
style: { backgroundColor: "#13a88a"}
});
}
Now i don't know why but the 'onPress' is never triggered.
Thank you for your answers!
If you want to execute the function by using 'this.changeStyle`, write your onPress like so:
<TouchableOpacity onPress={this.changeStyle}/>
If you're going to pass a function within the onPress prop that executes this.changeStyle write your onPress like so:
<TouchableOpacity onPress={() => this.changeStyle()}/>
P.S: Why do you have <TouchableHighlight/> inside a <TouchableOpacity/>? Just use one and add the onPress prop on it.
You need to import TouchableOpacity from react-native instead of importing it from react-native-gesture-handler. The version in react-native-gesture-handler is 100% broken. The version in react-native works.

TouchableHighlight onPress not working

I implemented a sign in page that worked up until I upgraded react-native.
The problem I'm having is that the onPress prop isn't being called:
<TouchableHighlight style={styles.button}
underlayColor='#f1c40f'
onPress={this.signIn}>
<Text style={styles.buttonText}>Sign In</Text>
</TouchableHighlight>
Here is my signIn function:
signIn: function(){
console.log("SignInAction signIn")
this.fetchData(); },
The signIn button appears to be depressed when I click it but the log statement isn't firing.
Try calling it like this:
onPress={ () => this.signIn() }>
It looks like the "this" in your function is bound to the wrong scope.
you can also do it like this:
onPress={this.signIn.bind(this)}>
the rest of code don't need change.
Also, if you don't wanna use bind and since we're using ES6 syntax, you could write your function out assigned as a const and arrow-function (within your component) rather than a function eg:
signIn = () => {
// code here
}
then you can still call it within the component like you already are without having to bind within the constructor or anywhere else:
<TouchableHighlight style={styles.button}
underlayColor='#f1c40f'
onPress={this.signIn}>
<Text style={styles.buttonText}>Sign In</Text>
</TouchableHighlight>
This should keep context of "this" consistent since signIn will be bound to the component only once on initialization.