React Native: can't call a parent method from child - react-native

I have this function in parent component, and I am trying to call this method/function in child , like so:
buttonPressed = () => {
console.log('button pressed')
}
<childComp ref={ref => this.feedback = ref}
onPress={this.buttonPressed}
/>
in child:
<Animated.View>
... // other views
<View>
<TouchableOpacity onPress={this.props.buttonPressed}> // calling here
...
</TouchableOpacity>
</View>
</Animated.View>
No matter what I tried , it didn't work.

you are passing onPress prop to child and calling buttonPressed in child. it should be like this :
<Animated.View>
... // other views
<View>
<TouchableOpacity onPress={this.props.onPress}> // calling here
...
</TouchableOpacity>
</View>
</Animated.View>

I think that in child component you should call to this.props.onPress(), because the name of the property thar you are passing is onPress. Also, don't forget to put () when you want to call the function. So it should be:
<Animated.View>
... // other views
<View>
<TouchableOpacity onPress={this.props.onPress()}> // calling here
...
</TouchableOpacity>
</View>
</Animated.View>

Related

How to call parent's function in react native?

How to call the parent's function in the child component?
I followed this answer, but it doesn't work for me. How to solve this?
React native how to call functions of parent class
This is my code.
Parent
<View>
<HeaderHome onClick={this.openDrawer} />
</View>
openDrawer() {
alert('I am clicked.')
}
Child component
<TouchableOpacity onPress={this.props.bind(this.props.onClick)} >
<Image source={url} />
</TouchableOpacity>
Take it a try:
Parent
<View>
<HeaderHome onClick={this.openDrawer} />
</View>
openDrawer = () => {
alert('I am clicked.')
}
Children
<TouchableOpacity onPress={() => { this.props.onClick()}} >
<Image source={url} />
</TouchableOpacity>

FlatList rendeItem component doesn't recognize `this` keyword

I have to call a function inside the renderItem function that is called for each item in a FlatList's data. The function will come from the component it comes from and uses a little of the component's state, however, it always returns an error that the method is undefined when it comes to getting that method or, for that matter, the data in the component's state.
Here's the method and how the FlatList looks like
renderItem({ item, index }) {
return (
<TouchableOpacity onPress={() => {this.goToStaffMemberPage(item.id)} }>
<View style={GenericStyles.styles.genericCard}>
<Text style={GenericStyles.styles.genericCardTitle}> {item.first_name.toUpperCase() + " " + item.last_name.toUpperCase()} </Text>
<Text style={GenericStyles.styles.genericCardDescription}> {item.role_name.toUpperCase()} </Text>
</View>
</TouchableOpacity>
);
}
<FlatList
data={this.state.staffList}
keyExtractor={(item, index) => index.toString()}
renderItem={this.renderItem}
contentContainerStyle={GenericStyles.styles.genericContainer}
/>
That's because you are not giving it access to this. You can either bind it (preferability in the constructor) doing:
constructor(props){
super(props);
this.renderItem.bind(this);
}
or using arrow function directly when you define renderItem:
renderItem = ({ item, index }) => {
return (
<TouchableOpacity onPress={() => {this.goToStaffMemberPage(item.id)} }>
<View style={GenericStyles.styles.genericCard}>
<Text style={GenericStyles.styles.genericCardTitle}> {item.first_name.toUpperCase() + " " + item.last_name.toUpperCase()} </Text>
<Text style={GenericStyles.styles.genericCardDescription}> {item.role_name.toUpperCase()} </Text>
</View>
</TouchableOpacity>
);
}

How can I set data in a state in FlatList?

I want to save product ID (item.id) in a state like productId.
I need to product Id for add product to cart.
When I click on TouchableOpacity working fine but productId always is 4.
I have three Item. The id of last item is 4 and first item is 2.
When I click on TouchableOpacity of product 1, id is 4 but should be 2.
I see IDs are OK When I print IDs in listView.
<FlatList
data={this.state.dataSource}
renderItem={({item}) =>
<View>
<View>
<Text>{item.title} - {item.type}</Text>
<Text>{item.id}</Text>
<TouchableOpacity onPress={this.decrementCount,()=>this.setState({productId:item.id})}>
<AntDesign name="minus" size={15} style={{color:'#fff'}}/>
</TouchableOpacity>
<TouchableOpacity onPress={this.incrementCount} activeOpacity={0.5}>
<AntDesign name="plus" size={15} style={{color:'#fff'}}/>
</TouchableOpacity>
</View>
</View>
}
/>
I think this line is your issue:
<TouchableOpacity onPress={this.decrementCount,()=>this.setState({productId:item.id})}>
First things first, you should define your render function on your class, and you should define your onPress function separate from that. For example:
class MyClass extends React.Component {
handlePress = (item) => {
this.decrementCount()
this.setState({productId: item.id})
}
renderItem = ({item, index}) => {
return (...code from above, but using this.handlePress rather than your onPress function as currently defined)
}
render() {
return (
<FlatList
data={this.state.dataSource}
renderItem={this.renderItem}
/>
)
}
}
I think the real reason that its not working for you right now is that you're trying to call this.setState as a callback in your onPress function. It would probably work as is if you changed your current onPress from:
onPress={this.decrementCount,()=>this.setState({productId:item.id})}
to
onPress={() => this.setState({productId:item.id}, this.decrementCount)}
as I'm fairly sure you can have a function called as a callback from this.setState.
Hope this helps!

How to get the style name and state name of a clicked element in React Native?

In the following, first example how do I check if the clickable element TouchableWithoutFeedback has the style named EntryBlock1?
render() {
return (
<TouchableWithoutFeedback style={styles.EntryBlock1} onPress={() => this.CheckIfHasStyles()}>
<View style={styles.redundantWrapperNumber1}>
<Text style={styles.redundantWrapperNumber2}>Click To Test For Style</Text>
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback style={styles.EntryBlock2} onPress={() => this.CheckIfHasStyle()}>
<View style={styles.redundantWrapperNumber1}>
<Text style={styles.redundantWrapperNumber2}>Click To Test For Style</Text>
</View>
</TouchableWithoutFeedback>
); // end return
} // end render
In the 2nd example, how can I check if TouchableWithoutFeedback has the state name EntryBlock1 ?
constructor (props) {
super(props);
this.state = {
EntryBlock1: [styles.entryBlockButton, styles.entryBlockButtonMin],
EntryBlock2: [styles.entryBlockButton, styles.entryBlockButtonMax],
}
}
render() {
return (
<TouchableWithoutFeedback style={this.state.EntryBlock1} onPress={() => this.CheckIfHasStateName()}>
<View style={styles.redundantWrapperNumber1}>
<Text style={styles.redundantWrapperNumber2}>Click To Test For Style</Text>
</View>
</TouchableWithoutFeedback>
); // end return
What I've Tried
Different stuff along the lines of the following..
CheckIfHasStyles =()=> {
var object = this.state;
var stringifiedObject = JSON.stringify(object);
var slicedObject = stringifiedObject.slice(2, 13);
if (slicedObject === 'EntryBlock1') {
alert('success');
} else {
alert('failure');
}
}
.. which actually works for one very specific example, but not when I have multiple state names as this.state gets all of them in one object and not just the state of the element clicked.
Note: My question is solely about getting attributes and their values. It is to help me develop a style of toggling styles on elements but I am only looking for attribute stuff in these answers as I would like to use attributes, if possible, for more than just toggling in the future.
You can pass it as parameter to your function directly like this:
render() {
return (
<TouchableWithoutFeedback style={styles.EntryBlock1} onPress={() => this.CheckIfHasStyles('EntryBlock1')}>
<View style={styles.redundantWrapperNumber1}>
<Text style={styles.redundantWrapperNumber2}>Click To Test For Style</Text>
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback style={styles.EntryBlock2} onPress={() => this.CheckIfHasStyle('EntryBlock2')}>
<View style={styles.redundantWrapperNumber1}>
<Text style={styles.redundantWrapperNumber2}>Click To Test For Style</Text>
</View>
</TouchableWithoutFeedback>
);
}
and check if you are receiving any parameter in your function and do what you want
based on If-else condition

React Native prevent touch bubbling to parent elements

If I want to prevent the onPress event on the View component propagating to the parent Touchable for the following Sample component, what's the best option other than wrapping the child view in a Touchable please?
export default function Sample (): Element<*> {
return(
<TouchableOpacity>
<View>
<Text>Sample</Text>
</View>
</TouchableOpacity>
);
}
In my case I simply put the View inside another TouchableOpacity (with activeOpacity to 1 to block any graphic effect):
export default function Sample (): Element<*> {
return(
<TouchableOpacity>
<TouchableOpacity activeOpacity={1}>
<View>
<Text>Sample</Text>
</View>
</TouchableOpacity>
</TouchableOpacity>
);
}