Call function onPress React Native - javascript

I just want to know how to call a function onPress. I've setup my code like this:
export default class Tab3 extends Component {
constructor(props) {
super(props);
this.state = {myColor: "green"};
}
handleClick = () => {
if (this.state.color === 'green'){
this.setState({myColor: 'blue'});
} else {
this.setState({myColor: 'green'});
}
}
render() {
return(
<View>
<Icon
name='heart'
color={this.state.myColor}
size= {45}
style={{marginLeft:40}}
onPress={() => handleClick(this)}
/>
</View>
)};
But when I try this, I'm getting error that can't find variable handleClick
Please help. I just want to know how to bind a function to a click event.

In you're render you're setting up the handler incorrectly, give this a try;
<View>
<Icon
name='heart'
color={this.state.myColor}
size= {45}
style={{marginLeft:40}}
onPress={this.handleClick}
/>
</View>
The syntax you're using would make sense for declaring an anonymous function inline or something but since your handler is defined on the class, you just reference it (not call it) using this.functionName in the props.

A little late to the party, but just wanted to leave this here if someone needs it
export default class mainScreen extends Component {
handleClick = () => {
//some code
}
render() {
return(
<View>
<Button
name='someButton'
onPress={() => {
this.handleClick(); //usual call like vanilla javascript, but uses this operator
}}
/>
</View>
)};

You need to reference the method with the this keyword.
<Icon
onPress={this.handleClick}
/>

you can also try this way of binding
this.handleClick = this.handleClick.bind(this)
and put this inside constructor. And while calling use this syntax
onPress = {this.handleClick}
This will surely solve your problem.

If you are not using class components, you can just drop the this
This function can handle the navigation for any route (as long as there is one screen with the name passed as the argument) removing the need for multiple handlers.
const navigation = useNavigation();
function handleNavigation(route) {
navigation.navigate(route);
}
and the button will look like this:
<Button onPress={() => handleNavigation("Menu")} ></Button>

Related

Calling function in react native outside component

My requirement
I am calling my function placed outside of the component and view in react native, but it throws errors saying the _this.myfunction is undefined. Its clearly not getting the reference for the function. Is it possible to achieve such feature in react native.
class App extends React.Component {
constructor(props) {
super(props);
}
render () {
return (
<View style={styles.container}>
<Button onPress={() => this.Myfunction()} style={styles.Button} title="Button"/>
</View>
);
}
}
Myfunction () {
alert('clicked');
}
Since you've defined the function outside of the class, you don't need to refer it by this. You can simply write onPress={() => Myfunction()} or onPress={Myfunction}
Also your function's syntax is wrong, add the function keyword before it
function Myfunction () {
alert('clicked');
}

What is the best way to call a handling function in React?

I was reading the ReactJs documentation about Handling events and I wondered what the best practice is for calling a handling function in a component.
My question is very simple (and even basic I think): what should be used between onClick={handleClick} or onClick={this.handleClick] ?
I wonder after seeing these two pieces of code in which handleClick is called without the keyword this in the first code and with in the second code.
ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
They are 2 different situations.
onClick={handleClick} is used in functional component, in a function this key work is refer to the place when the function is call, you don't use this in functional component.
onClick={this.handleClick] is used in class component. In class you need to use this key work to access class property which is function in this case.

How to pass function and data from component class to stateless class in React Native?

I am working with react native and I want to pass function and some data from Component class to another Stateless class, but I could not make to passing function and data part.
Here you can see my Component class:
class Classroom extends Component {
constructor(props, context) {
super(props, context);
};
state = {
isLightOn: false,
title : "Turn light on "
}
onPress() {
this.setState({isLightOn: !this.state.isLightOn})
console.log(this.state.isLightOn)
this.setState({title:this.state.isLightOn===false ?"Turn light off":"Turn light on"})
}
render() {
return (
<View style={styles.blue}>
<LightBulb isLightOn={this.state.isLightOn}> </LightBulb>
<LightButton onPress={this.onPress} isLightOn={this.state.isLightOn} title={this.state.title} > </LightButton>
</View>
);
}
}
Firstly, I want to pass isLightOn and title datas to my LightButton class (which mean to my stateless class). After that, I want to use onPress function inside of my Stateless class, but I cannot use. I am taking that error:
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
I also LightButton onPress={this.onPress} remove parenthesis, but still taking error.
Here is my my Stateless class
const LightButton = ({onPress,isLightOn,title}) => (
<View style={styles.red}>
<Button
title= {title}
onPress={() => {}
}
/>
</View>
)
I want to use onPress function and datas inside of the this class.
As a result, How can I pass function and data to that class?
The main issue here is that you need to declare onPress using an arrow function or bind it to the component's this value within the constructor. Otherwise it wouldn't have access to the correct this value. Other than that, the way you were passing props into components is perfectly fine.
I also merged your two set state calls in onPress to one as it's easier.
In LightButton, I set it up like this to pass the onPress function down to the button:
const LightButton = ({ onPress, isLightOn, title }) => (
<div style={{backgroundColor:'red'}}>
<Button title={title} onPress={onPress} />
</div>
);
(I set it up using react, but the issues at hand are more of a JS issue than a React/ReactNative one, so the advice should still be valid :) )
const { Component } = React;
const View = 'div';
const Button = (({title,onPress})=><button onClick={onPress}>{title}</button>);
const LightBulb = ({ isLightOn }) => {
return <div className={'LightBulb' + (isLightOn ? ' on' : '')} />;
};
const LightButton = ({ onPress, isLightOn, title }) => (
<div style={{backgroundColor:'red'}}>
<Button title={title} onPress={onPress} />
</div>
);
class Classroom extends Component {
state = {
isLightOn: false,
title: 'Turn light on ',
};
onPress=()=> {
console.log(this.state.isLightOn);
this.setState({
title:
this.state.isLightOn === false ? 'Turn light off' : 'Turn light on',
isLightOn: !this.state.isLightOn
});
}
render() {
return (
<div style={{backgroundColor:'blue'}}>
<LightBulb isLightOn={this.state.isLightOn}> </LightBulb>
<LightButton
onPress={this.onPress}
isLightOn={this.state.isLightOn}
title={this.state.title}
>Button</LightButton>
</div>
);
}
}
ReactDOM.render(<Classroom />, document.querySelector('#root'));
.LightBulb {
height: 50px;
width: 50px;
border-radius: 50px;
background-color: black;
}
.LightBulb.on {
background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
You can assign it like
const LightButton = ({onPress,isLightOn,title}) => (
...
onPress={onPress}
...
or with an arrow function if you need to pass arg inside
onPress={()=>onPress(someArg)}
do notice that you either don't put () at all, or twice () => func() for not run the function while it is just loads and not clicked.
unrelated directly to your issue but something that you encounter is inside onPress by doing like so
this.setState({isLightOn: !this.state.isLightOn})
console.log(this.state.isLightOn)
this.setState({title:this.state.isLightOn===false ?"Turn light off":"Turn light on"})
setState it is an async call, and therefore second setState usage not guaranteed to refer the state as you expect, use setState({ ... }, () => callback()) or all at one line and accords to prev state
this.setState({isLightOn: !this.state.isLightOn, title: !this.state.isLightOn===false ?"Turn light off":"Turn light on"})
First thing you did wrong is your state instantiating !
you need to instantiate your state in the constructor block like:
constructor(props, context) {
super(props, context);
this.state = { counter: 0 };
}
onPress() you use this for your function which is not recommended in react native or any other language , those are dedicated functions and methods of React Native
For passing a parameter or calling a function it is better to use these patterns ====>
onPress={() => urFunction()} with parenthesis or
onPress={urFunction} without parenthesis
Do the modifications I hope it helps <3

React Native Touchable Opacity functions

I have two functions in my React Native app, and I need my TouchableOpacity to call both when pressed. To do so I tried to simply use an arrow function in the onPress method with both functions inside, but this doesn't work. I assume it's something to do with scope, but I'm not sure. Both functions work correctly when simply passed into the onPress method alone. Here's the code (I've trimmed it a lot for readability) Please help.
export class CreateItem extends React.Component {
constructor(props){
super(props);
}
sendData = () => {
itemData = this.state.item;
this.props.action(itemData); //the action function alters the parent state (this function works fine every other time)
}
render(){
return(
<TouchableOpacity
onPress={() => {
this.sendData;
this.props.hide; //This function is passed from the parent and works fine in other scenarios
}}
>
<Text>Add Item</Text>
</TouchableOpacity>
)
}
you missed the parentheses of functions
export class CreateItem extends React.Component {
constructor(props){
super(props);
}
sendData = () => {
itemData = this.state.item;
this.props.action(itemData); //the action function alters the parent state (this function works fine every other time)
}
render(){
return(
<TouchableOpacity
onPress={() => {
this.sendData();
this.props.hide(); //This function is passed from the parent and works fine in other scenarios
}}
>
<Text>Add Item</Text>
</TouchableOpacity>
)
}

React Native: can't a method be used from 'routeMapper'?

I’m using react native drawer of https://github.com/root-two/react-native-drawer
I am trying to call the method openDrawer() by passing in variable into NavigationBarRouteMapper. I tried logging inside NavigationBarRouteMapper, and it logs the variable passed in correctly. But when it used inside the NavigationBarRouteMapper, by clicking the Left Navigation button of ‘Open Drawer’, it does not do anything:
class drawerPractice extends Component {
...
openDrawer(){
this._drawer.open()
}
render() {
return (
<Drawer
content={<DrawerPanel/>}
openDrawerOffset={100}
ref={(ref) => this._drawer = ref}
type='static'
tweenHandler={Drawer.tweenPresets.parallax}
>
<Navigator
configureScene={this.configureScene}
initialRoute={{name: 'Start', component: Start}}
renderScene={this.renderScene}
style={styles.container}
navigationBar={
<Navigator.NavigationBar
style={styles.navBar}
routeMapper={NavigationBarRouteMapper(this.openDrawer)}
/>
}
/>
</Drawer>
);
}
}
var NavigationBarRouteMapper = openDrawer => ({
LeftButton(route, navigator, index, navState){
return(
<TouchableHighlight onPress={()=>{openDrawer}}>
<Text>Open Menu</Text>
</TouchableHighlight>
)
}
},...
Why may be the issue?
On your constructor() method add this: this.openDrawer = this.openDrawer.bind(this);
You're likely using this on the wrong scope.
There is a common confusion when working with React components and the new ES6 extends syntax. If you use React.createClass, it will bind this to all of your functions, but when using the ES6 approach of extends React.Component you have to bind your functions manually.
You can do it either inline using
<TouchableHighlight onPress={()=>{this.openDrawer.bind(this)}}>
Alternatively, you can add to your constructor, after super():
this.openDrawer = this.openDrawer.bind(this);
Personally I like this approach as I find this code a bit easier to read.
For more information about the ES6 way, check this link.

Categories

Resources