I am having trouble with react-native onPress Feature. The onPress should only work when it is actually been triggered by a touch event (i suppose) , that is when i press the button on the screen. But it seems the onPress gets triggered itself when the render function is called. When i try to press manually, it doesn't work.
import React, { Component } from 'react';
import { PropTypes, Text, View ,Alert } from 'react-native';
import { Button } from 'react-native-material-design';
export default class Home extends Component {
render() {
return (
<View style={{flex:1}}>
<Button value="Contacts" raised={true} onPress={this.handleRoute('x')} />
<Button value="Contacts" raised={true} onPress={this.handleRoute('y')} />
<Button value="Contacts" raised={true} onPress={this.handleRoute('z')} />
</View>
);
}
handleRoute(route){
alert(route) // >> x , y, z
}
}
module.exports = Home;
What am i missing ? Is there something wrong with the way i have assigned or this is some bug ?
Any suggestion is highly appreciated.
Video
try to change
onPress={this.handleRoute('x')} // in this case handleRoute function is called as soon as render happen
to
onPress={() => this.handleRoute.bind('x')} //in this case handleRoute doesn't called as soon as render happen
You can change to this:
onPress={this.handleRoute.bind(this, 'x')}
or this:
onPress={() => this.handleRoute('x')}
The reason is that onPress takes a function as an argument. In your code, you are calling the function and returning the result immediately (when render is called) rather than referencing the function for React to call later on the press event.
The reason you need the bind(this) is because the function loses it's bound instance when you just do (this.handleRoute) and you have to tell it which this to use. The bind function takes the other arguments to call on the function later. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind for more descriptive info on bind.
There is another way in which you can bind in the constructor. You can read about ways to handle this in React here: https://facebook.github.io/react/docs/handling-events.html
onPress={this.handleevent.bind(this, 'A')}
or use this:
onPress={() => this.handleevent('B')}
Change
onPress={this.handleRoute('x')}
to
onPress={()=>this.handleRoute('x')}
Otherwise, the function gets invoked as soon as the render method gets called.
The reason for such behaviour is on every render, reference to the function is created.
So, to avoid that, use bind function OR arrow function to call on onPress
Related
On react native, why can I call the return function to pass a prop, but when passing it in a composed function it won't work?
This works
const pop = props.onPress;
...
<TouchableOpacity style={styles.okButton} onPress={pop}>
But,
function closee() {
console.log('aaadsedf');
props.onPress;
}
...
<TouchableOpacity style={styles.okButton} onPress={closee}>
shows log working ok, but doesnt trigger the props.onPress
So how to properly call the onPress?
how to properly pass the composed function?
You need to call it like:
function closee() {
console.log('aaadsedf');
props.onPress();
}
I am experiencing some behavior of a ReactNative Switch that I cannot explain.
I have a very simple switch (see code below). It has a fixed value prop and its onValueChange-callback is only a log. As a switch is a controlled component, I thought the UI is only rerendered when the value prop changes.
Despite my assumptions the switch shows a quick animation of toggling to false and then jumps back to true. Why is that happening? Does it have to do with the iOS specific component that is used by ReactNative?
import React from "react";
import { Switch, View } from "react-native";
export const SwitchCell = () => {
return (
<View>
<Switch onValueChange={() => console.log("Test")} value={true} />
</View>
);
};
If you want to block the event there is a prop for switch called "onChange" where as parameter you will receive the event and the new value, you can execute a check to decide if will be necessary to set the new property o if it won't change.
In case you doesn't want to change the value of switch you have to call the methods "preventDefault()"
This is the code implementation in screenshot. I just created a simple application that contains one button and one input field where I'm saving the input text and printing in the log on console after button press but it shows in error with **const [enterGoal, setGoalState] = useState('')**. Can someone have a look on it?
The problem is you are using a class component and hooks are meant to be used in functional components. So thats the error. If you are using class try using setState method to update state and also define states in constructor. like
constructor(props){
this.state={
nameOfPerson:'robert'
}
}
and inside any function do this.setState({nameOfPerson:'wowo'}) to change it,,
you are using hooks in class components .hooks are working in functional componets
for example
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
for more check documentation
I'm using useState to keep the value of an input, and I need make some stuff when the taps a specific key, so I'm try to use onKeyPress, but the method used to update the state is not working, any help aprecciated :)
Here how the code looks like:
...
function handleKeyPress(event) {
// This code looks like is not running, why?
setMessageInput('asdasdasdasd')
}
...
<TextInput onKeyPress={handleKeyPress} />
...
It looks like you need to bind the function to the onKeyPress event handler. You can easily accomplish this by using an arrow function.
function handleKeyPress(event) {
setMessageInput('asdasdasdasd')
}
...
<TextInput onKeyPress={(e) => handleKeyPress(e)} />
The problem with yours is a javscript statement , where functions in javascript needs explicit binding of this in class components and in functional components you can achieve the same by using fat arrow functions.
So try replacing the code with the below
const handleKeyPress = (event) => {
setMessageInput('asdasdasdasd')
}
...
<TextInput onKeyPress={(e) => handleKeyPress(e)} />
Hope it helps. feel free for doubts
I solved this problem, its a problem with async execution of another handler
I have multiple buttons in a screen and all are independent like one button is for navigating to next page, another one is for a popup calendar, etc. When I click quickly on all these buttons, all clicks are triggered and I tried using disabling the buttons by using a boolean state variable. But still I can click on the button within the time I set the state. So is there any way to prevent this to happen?
Thanks in Advance!
You can easily achieve this behavior by using setState method. However be careful, as set state is asynchronous. For simple scenario you can to do it like this:
constructor(props) {
super(props);
this.state = {
enableButton: false
};
}
And then use your button or TouchableOpacity like this:
<TouchableOpacity
disabled={this.state.enableButton}
onPress={() => handleMe()}>
<Text>
{text}
</Text>
</TouchableOpacity>
And then for enabling your button:
handleMe() {
this.setState({
enableButton: true
});
}
Let me know, if you are still confused.
There might be a issue with function binding. The function might not have been binded which makes them being called even without tap.