I'm trying to get a menu item to navigate to another page but for some reason it wont let me do it. I'm a little confused as to how you go about it and any help is welcome!
Import here:
import { NavigationScreenProp } from "react-navigation";
Here is more code:
interface NotificationDropdownProps {
navigation: NavigationScreenProp<any, any>;
}
Here is where function is called:
function renderNotification(notification: INotification) {
return (
<MenuOption
onSelect={() => {
if (notification.type == INotificationType.SYSTEM) {
this.testFunction();
}
}}
>
<View style={[styles.notificationContainer]}>
<View style={styles.iconArea}>
<View style={[styles.iconCircle]}>
<Icon
name={this.getIconType(notification.type)}
color={this.notificationColor(notification.type)}
size={26}
/>
</View>
</View>
<View>
<Text>{notification.text}</Text>
<Text>
{this.getDate(new Date(notification.dateCreated))}
</Text>
</View>
</View>
</MenuOption>
);
}
Test Function:
testFunction(){
this.props.navigation.navigate('NextPage')
};
Error:
undefined is not an object(evaluating'_this2.props.naviagtion.navigate)
Where the function is called:
<View>
<Text>
Notifications
</Text>
{this.props.notifications.length > 0 ? (
<FlatList
contentContainerStyle={{ borderRadius: 10 }}
data={this.props.notifications.slice(0, 5)}
renderItem={({ item }) => this.renderNotification(item)}
keyExtractor={this.keyExtractor}
/>
) : (
<Text>No Notifications!</Text>
)}
</View>;
try with an arrow function to avoid using the context of the function.
testFunction = () => {
this.props.navigation.navigate('NextPage')
};
Related
How to pass parent Flatlist's index value to child Flatlist's function so I can use it in function and change value by setState.
So how to pass parent Flatlist's index value to child Flatlist's function so I can use it in function and change value by setState.
It starts with a list that built-in state
constructor(props) {
super(props);
this.state = {
list: [
{
question: 'il veicolo ha la gomma forata?',
answers: [
{
radioButtonValue: false,
text: strings.CONFIRMVIEW_yes,
},
{
radioButtonValue: true,
text: strings.CONFIRMVIEW_no,
},
],
},
]
}
}
checkBoxSelection = (item, index) => {
// if (item.radioButtonValue == index) {
// this.list.answers[index].radioButtonValue = true
// }
console.log(this.state.list[0].answers[index].radioButtonValue)
}
_renderItem = ({ item, index }) => {
return (
<View style={styles.cellView}>
<Text style={styles.questionText}>
{item.question.toUpperCase()}
</Text>
<FlatList
data={item.answers}
horizontal={true}
showsHorizontalScrollIndicator={true}
scrollEnabled={true}
bounces={false}
renderItem={this._renderItemOptions}
/>
{/* <View style={styles.yesNoRadioButtonView}>
<View style={styles.yesChekboxView}>
<TouchableOpacity onPress={ () => {console.log("TEST1"); this.checkBoxSelection()} }>
<Image source={(item.answers == index) ? AppImages.radioOn : AppImages.radioOff} style={styles.radioButton} />
</TouchableOpacity>
<Text style={styles.yesNoText}>
{strings.CONFIRMVIEW_yes}
</Text>
</View>
<View style={styles.noRadioButtonView}>
<TouchableOpacity onPress={() => { this.checkBoxSelection.bind(this) }}>
<Image source={(item.answers == 0) ? AppImages.radioOn : AppImages.radioOff} style={styles.radioButton} />
</TouchableOpacity>
<Text style={styles.yesNoText}>
{strings.CONFIRMVIEW_no}
</Text>
</View>
</View> */}
</View>
)
}
_renderItemOptions = ({ item, index }) => {
return (
<View>
<View style={styles.yesNoRadioButtonView}>
<TouchableOpacity onPress={() => { this.checkBoxSelection(item, index) }}>
<View style={styles.yesChekboxView}>
<Image
source={item.radioButtonValue ? AppImages.radioOn : AppImages.radioOff}
style={styles.radioButton}
/>
<Text style={styles.yesNoText}>
{item.text}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
)
}
render() {
return (
<Container>
<Content style={styles.container}>
<FlatList
data={this.state.list}
showsVerticalScrollIndicator={false}
scrollEnabled={false}
bounces={false}
renderItem={this._renderItem}
/>
</Content>
<SafeAreaView>
<TouchableOpacity
style={[LayoutStyle.appBtn1]}
>
<Text style={[LayoutStyle.appBtnText1]}>
{strings.DAMAGE_SURVEY_comeOn.toUpperCase()}
</Text>
</TouchableOpacity>
</SafeAreaView>
</Container>
)
}
In Parent Flatlist's renderItem function
replace
renderItem = { () => {this.renderItemOptions(item, index)}}
with
renderItem={(childData) => this._renderItemOptions(childData, index)}
and then in child Flatlist's renderItemOption function need to get parentIndex with another name.
_renderItemOptions = ({ item, index }, parentIndex) => {
console.log("hello")
return (
<View>
<View style={styles.yesNoRadioButtonView}>
<TouchableOpacity onPress={() => { this.checkBoxSelection(item, index, parentIndex) }}>
<View style={styles.yesChekboxView}>
<Image
source={item.radioButtonValue ? AppImages.radioOn : AppImages.radioOff}
style={styles.radioButton}
/>
<Text style={styles.yesNoText}>
{item.text}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
)
}
Try updating your renderItem prop in your FlatList to explicitly pass the index
renderItem={({item, index}) => this._renderItemOptions(item, index)}
I am trying to render the child component on onPressevent, the console.log works fine but components in the return function doesn't works.
Parent component:
onPress = (img,title,content) => {
this.setState({
show:true,
img:img,
title:title,
content:content
})
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<TouchableOpacity
onPress={() => this.onPress(item.urlToImage,item.title,item.content)}
>
<View style={styles.picsCont}>
<Image style={styles.pics} source={{uri: item.urlToImage}}/>
<Text style={{color:'white', fontSize: 15, fontWeight: '700', paddingTop:10}}>
{item.title}
</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={item => item.title}
/>
{this.state.show ?
<NewsView
img={this.state.img}
title={this.state.title}
content={this.state.content}
/> :
null
}
</View>
);
}
}
Child Component:
export default class NewsView extends Component {
render() {
console.log(this.props.img)
return (
<View style={styles.container}>
<Image style={styles.picsCont} source={{uri:this.props.img}} />
<Text style={styles.news}>{this.props.title}</Text>
<Text style={styles.news}>{this.props.content}</Text>
</View>
)
}
}
Thanks for the help...!
It might be the styles. If your child component has position:'absolute', it´s probably under your parent component, you can try to put on your child component view zIndex:10
Please find my code below and help me for adding item click listener for the items in the grid view. Please find the link which I followed library link.
And I need to display the name in an alert when the user clicks on each item in the gridlist. Styles are not included in the code
Thanks in Advance
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableWithoutFeedback
} from 'react-native';
import GridLayout from 'react-native-layout-grid';
class HomeScreen extends Component {
renderGridItem = (props) => (
<View style={styles.item} >
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</View>
);
render() {
const items = [];
for (let x = 1; x <= 30; x++) {
items.push({
name: `Grid ${x}`
});
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Grid Layout
</Text>
<View style={styles.flex}>
<GridLayout
items={items}
itemsPerRow={2}
renderItem={this.renderGridItem}>
</GridLayout>
</View>
</View>
);
}
}
export default HomeScreen;
Instead of using <View> in your renderGridItem, you could use one of the touchables component (react native doc).
For example with <TouchableOpacity >:
renderGridItem = (props) => (
<TouchableOpacity style={styles.item} onPress={() => this.showAlert(props.name)}>
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</TouchableOpacity>
);
showAlert = (name) => {
Alert.alert(
'Alert Title',
`The user name is: ${name}`,
[
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
}
Why don't you wrap renderGridItem in a TouchableWithoutFeedback?
renderGridItem = (props) => (
<TouchableWithoutFeedback onPress={()=> Alert.alert(props.name)}>
<View style={styles.item} >
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</View>
<TouchableWithoutFeedback />
);
Also you will need to import Alert from react-native.
I have a component call ButtonLayout.js
export const ButtonLayout = () => {
return (
<View style={styles.row}>
<TouchableOpacity >
<Text>Book Now</Text>
</TouchableOpacity>
<TouchableOpacity >
<Text>Schedule</Text>
</TouchableOpacity>
</View>
)
}
and i have import this component to another common component called mapComponent and it look like following.
return (
<View style={styles.container}>
<MapView
provider={MapView.PROVIDER_GOOGLE}
style={styles.map}
region={this.props.region}
>
<MapView.Marker
coordinate={this.props.region}
pinColor='green'
/>
</MapView>
<ButtonLayout style={{ marginBottom: 5 }} />
</View>
);
so my question is how can i handle the onPress() function of the buttons in ButtonLayout.js from index.js ?
Make your ButtonLayout component accept callback props, like so:
export const ButtonLayout = ({onBook, onSchedule}) => (
<View style={styles.row}>
<TouchableOpacity onPress={onBook}>
<Text>Book Now</Text>
</TouchableOpacity>
<TouchableOpacity onPress={onSchedule}>
<Text>Schedule</Text>
</TouchableOpacity>
</View>);
Then, pass the callbacs in the parent component’s render function as props
<ButtonLayout onBook={…} onSchedule={…} />
Don’t forget to bind the context to the callbacks
In your button Buttonlayout.js define like this:
<TouchableOpacity onPress={() => this.props.onPress()}>
<Text>Book Now</Text>
</TouchableOpacity>
And define onPress function on each file you use this component just like.
<ButtonLayout style={{ marginBottom: 5 }} onPress={() => {'your logic..'}}/>
Define your callback variables in ButtonLayout and add them to your touchables.
export const ButtonLayout = ({ onBookPress, onSchedulePress }) => {
return (
<View style={styles.row}>
<TouchableOpacity onPress={onBookPress}>
<Text>Book Now</Text>
</TouchableOpacity>
<TouchableOpacity onPress={onSchedulePress} >
<Text>Schedule</Text>
</TouchableOpacity>
</View>
)
}
Define your callbacks in index:
indexOnBookPress = () => {
...do something
}
indexOnSchedulePress = () => {
...do something
}
return (
<View style={styles.container}>
<MapView
provider={MapView.PROVIDER_GOOGLE}
style={styles.map}
region={this.props.region}
>
<MapView.Marker
coordinate={this.props.region}
pinColor='green'
/>
</MapView>
<ButtonLayout style={{ marginBottom: 5 }} onBookPress={this.indexOnBookPress} onSchedulePress={this.indexOnSchedulePress} />
</View>
);
I have used FlatList in multiple places in my app previously without any issues, but now when I created a new one it doesn't seem to register touches/swipes correctly. Only like 1/6 touches seem to register.
See the video here: https://photos.app.goo.gl/NZCtVYX6GLVCQN392
This is how I use the FlatList:
render() {
return (
<Container>
...
<FlatList
data={this.state.exercises}
renderItem={({item}) =>
<SetsRepsAndWeightItem exercise={item}/>
}
keyExtractor={item => item.name}
style={style.list}
/>
</Container>
);
}
And the SetsRepsAndWeightItem:
render() {
return (
<View style={style.container}>
<View style={style.header}>
<Text style={style.headerText}>{this.props.exercise.name}</Text>
</View>
<View style={style.about}>
<TouchableWithoutFeedback onPress={this.handleSetsPressed}>
<StatisticNumber metric="Sets" value={7}/>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={this.handleRepsPressed}>
<StatisticNumber metric="Reps" value={5}/>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={this.handleWeightPressed}>
<StatisticNumber metric="kg" value={35}/>
</TouchableWithoutFeedback>
</View>
</View>
);
}
handleSetsPressed = () => {
console.log("sets pressed");
}
handleRepsPressed = () => {
console.log("reps pressed");
}
handleWeightPressed = () => {
console.log("weight pressed");
}
Also: the TouchableWithoutFeedback elements are not calling their onPress functions when they are touched.
The Container is as simple as this:
export default class Container extends Component {
static propTypes = {
children: Proptypes.any,
backgroundColor: Proptypes.string
};
render() {
const containerStyles = StyleSheet.flatten([
style.container,
this.props.backgroundColor ? { backgroundColor: this.props.backgroundColor } : null,
]);
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={containerStyles}>
{this.props.children}
</View>
</TouchableWithoutFeedback>
);
}
}
The following two fixes solved the issues for me:
Remove the onPress={() => Keyboard.dismiss()} from the Container component
Move the TouchableWithoutFeedback into the StatisticNumber component, and pass onPress as a prop from SetsRepsAndWeightItem