React Native Touchable Opacity functions - javascript

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>
)
}

Related

React Native - Using Props for Modal

I am trying to use modal on my application but I want to separated into different classes as App.js and /components/modal. The problem I encountered is I couldn't pass the props properly. Here is my codes.
I imported modal.
import InfoModal from '../components/InfoModal';
I created state.
state = {modalVisible: false}
The visible function on press.
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
Calling component.
render() {
const { modalVisible } = this.state;
return (
<InfoModal visible= {modalVisible} />
<TouchableOpacity onPress={() => this.setModalVisible(true)} ><Text style={styles.infoButton}>Info</Text></TouchableOpacity>
)}
I didn't understand what prop should I set and how, to work it properly.
Since you have a render method, I assume your App.js is a Class component.
You can create a state on the constructor like that
class App extends React.Component {
constructor(props){
super(props);
this.state = {
modalVisible: false,
}
}
// rest of the class
}
Your function for changing the modal's visibility should be like that
setModalVisible = (visible) => {
this.setState({modalVisible: visible});
}
That's how you control the state on the App class.
And for your modal, you pass App.state.modalVisible as a prop.
<InfoModal visible={this.state.modalVisible} />
When you use setState, all the components receiving that new value as a prop will properly update
use state and method inside Modal component and toggle it by using modal reference.
Put
const { modalVisible } = this.state;
and
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
in InfoModal.js
then use it like this
render() {
return (
<InfoModal ref={(c)= this.infoModal=c }visible= {modalVisible} />
<TouchableOpacity onPress={() => this.infoModal.setModalVisible(true)} ><Text style={styles.infoButton}>Info</Text></TouchableOpacity>
)

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');
}

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

using setState after function

i try it using setState after function in react, first run function , function finished after run setState({example:'example1'}) , how i can do it,
click button run loaded Variable with this.setState({loaded:false}), I will do the function setstate after the runtime this.setState({loaded:true}), how can it be done with a technique, i will use other code
container = () => { return (Balabla)} // is finish after 2.select
this.setState({loaded:true})
export default class search extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded:true
}
}
render(){
return(
<Loader loaded={this.state.loaded}/>
{this.container()}
)}
}
Probably you're asking for this, If I'm not wrong. You need an event-handler (onClick here) to call your respective function which changes the state. And also if your function is a paramless function, you shouldn't use the () in react while calling it.
container = () => { this.setState({loaded:true})}
render(){
return(
<Loader loaded={this.state.loaded} onClick={this.container}/>
)}

Call function onPress React Native

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>

Categories

Resources