I want to select the elements rendered using json array data,
i am rendering the elements using json array where only most recent clicked element is getting select,i want to select every clicked element,like state of previously clicked element should be saved.
In simple words when the element is clicked first time then it will be selected and when i click next element then the previous clicked element should remain selected.Click here to check image
import React, {useContext} from 'react';
import {
Dimensions,
Image,
StatusBar,
Text,
TouchableHighlight,
} from 'react-native';
import {Box, Button, ScrollView} from 'native-base';
import {useState} from 'react';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import {styles} from './createHabitStyles';
import {ApplicationContext} from '../../../context/application_ctx';
import {IconCheck, IconCircleBack} from '../../../svgIcons/icons';
export function ChooseTechnique({navigation, choose}) {
const [chooseButton, setChooseButton] = useState();
const {habitNavigation,setHabitNavigation,chooseSpan} =
useContext(ApplicationContext);
const {techniques, setTechniques} = useContext(ApplicationContext);
let techniqueChooser = [
{button: 'Mood Journal',src:require('../../../assets/images/techniqueBackgrounds/journal.jpg')},
{button: 'Meditation',src:require('../../../assets/images/techniqueBackgrounds/meditation.jpg')},
{button: 'ABCD',src:require('../../../assets/images/techniqueBackgrounds/abcd.jpg')},
{button: 'Optimism',src:require('../../../assets/images/techniqueBackgrounds/optimism1.jpg')},
{button: 'Journal',src:require('../../../assets/images/techniqueBackgrounds/journal.jpg')},
{button: 'Motivation',src:require('../../../assets/images/techniqueBackgrounds/motivation.jpg')},
{button: 'Defusion',src:require('../../../assets/images/techniqueBackgrounds/defusion.jpg')},
{button: 'Values',src:require('../../../assets/images/techniqueBackgrounds/goals.jpg')},
{button: 'Goals',src:require('../../../assets/images/techniqueBackgrounds/values.jpg')},
{button: 'Thought Record',src:require('../../../assets/images/techniqueBackgrounds/thought.jpg')},
{button: 'Breathe',src:require('../../../assets/images/techniqueBackgrounds/breathe.jpg')},
];
return (
<>
<StatusBar
backgroundColor={'#F5F5F5'}
translucent={false}
barStyle={'dark-content'}
/>
<Box style={styles.MainBox}>
<ScrollView>
<Box style={{height: '6%', alignItems: 'center'}}>
<Text style={styles.stepperTxt}>Create Habit</Text>
</Box>
<IconCircleBack
onPress={() => setHabitNavigation(0)}
style={{...styles.iconBack, top: '2.2%'}}
/>
<Box style={styles.choosenBox}>
<Box
style={styles.choosenButton}>
<Text style={{fontSize: 15, color: '#5D535C'}}>
{chooseSpan.but}
</Text>
</Box>
{chooseButton !== undefined ? (
<Box
style={styles.choosenButtonDynamic}>
<Text style={{fontSize: 15, color: '#5D535C'}}>
{techniques}
</Text>
</Box>
) : (
''
)}
</Box>
<Box style={{height: '6%', marginTop: '2%'}}>
<Text style={styles.headTxt}>Choose a technique</Text>
<Text
style={styles.subHeading}>
Create a habit from any one of your susbcribed techniques
</Text>
</Box>
<Box style={{height: 1050}}>
<Box style={{alignItems: 'center'}}>
{techniqueChooser.map((data, i) => {
return (
<TouchableHighlight
key={i}
underlayColor={'none'}
onPress={() => {
setChooseButton(i), setTechniques(data.button);
}}
style={styles.cardTechniques}>
<>
{chooseButton === i ? <IconCheck style={{position:'absolute',right:10,bottom:"10%",zIndex:1}} /> : ""}
<Image
style={styles.imageOptimism}
resizeMethod="scale"
resizeMode="cover"
source={data.src}
/>
<Image
style={{
...styles.imageBackdrop,
display: `${chooseButton === i ? 'none' : 'flex'}`,
}}
resizeMethod="scale"
resizeMode="cover"
source={require('../../../assets/images/techniqueBackgrounds/backdrop.png')}
/>
<Box
style={styles.buttonTechnique}>
<Text
style={{
fontSize: 14,
fontWeight: 'bold',
color: '#5D535C',
}}>
{data.button}
</Text>
</Box>
</>
</TouchableHighlight>
);
})}
</Box>
</Box>
</ScrollView>
<Box
style={{
position: 'absolute',
bottom: '3%',
width: '100%',
alignItems: 'center',
}}>
<Button
isDisabled={chooseButton !== undefined ? false : true}
style={{
...styles.button2,
backgroundColor: `${
chooseButton !== undefined ? '#36A2D0' : '#6D7A82'
}`,
}}
isLoadingText="Continue"
spinnerPlacement="end"
onPress={() =>{techniques === "Meditation" ? setHabitNavigation(4) : techniques === 'Breathe' ? setHabitNavigation(6) : setHabitNavigation(3)}}>
<MaterialIcons
name="arrow-forward-ios"
style={{
fontSize: 20,
color: `${chooseButton !== undefined ? 'white' : 'black'}`,
}}
/>
</Button>
</Box>
</Box>
</>
);
}
Related
I have rendered data from an array / JSON and its shows on screen. When I click on an option its heiglights the box on which I have clicked. But I want to heightlight multiple options or want to choose multiple options from array.
I am not getting how to do that. It only shows only one option and when I click click on another otion it heighlights the option but dehighlights the previous option.
Please suggest me solution for that. I have share image and code below -
Image:
enter image description here
Code:
import React, {useContext} from 'react';
import {
Dimensions,
Image,
StatusBar,
Text,
TouchableHighlight,
} from 'react-native';
import {Box, Button, ScrollView} from 'native-base';
import {useState} from 'react';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import {styles} from './createHabitStyles';
import {ApplicationContext} from '../../../context/application_ctx';
import {IconCheck, IconCircleBack} from '../../../svgIcons/icons';
export function ChooseTechnique({navigation, choose}) {
const [chooseButton, setChooseButton] = useState();
const {habitNavigation,setHabitNavigation,chooseSpan} =
useContext(ApplicationContext);
const {techniques, setTechniques} = useContext(ApplicationContext);
let techniqueChooser = [
{button: 'Mood Journal',src:require('../../../assets/images/techniqueBackgrounds/journal.jpg')},
{button: 'Meditation',src:require('../../../assets/images/techniqueBackgrounds/meditation.jpg')},
{button: 'ABCD',src:require('../../../assets/images/techniqueBackgrounds/abcd.jpg')},
{button: 'Optimism',src:require('../../../assets/images/techniqueBackgrounds/optimism1.jpg')},
{button: 'Journal',src:require('../../../assets/images/techniqueBackgrounds/journal.jpg')},
{button: 'Motivation',src:require('../../../assets/images/techniqueBackgrounds/motivation.jpg')},
{button: 'Defusion',src:require('../../../assets/images/techniqueBackgrounds/defusion.jpg')},
{button: 'Values',src:require('../../../assets/images/techniqueBackgrounds/goals.jpg')},
{button: 'Goals',src:require('../../../assets/images/techniqueBackgrounds/values.jpg')},
{button: 'Thought Record',src:require('../../../assets/images/techniqueBackgrounds/thought.jpg')},
{button: 'Breathe',src:require('../../../assets/images/techniqueBackgrounds/breathe.jpg')},
];
return (
<>
<StatusBar
backgroundColor={'#F5F5F5'}
translucent={false}
barStyle={'dark-content'}
/>
<Box style={styles.MainBox}>
<ScrollView>
<Box style={{height: '6%', alignItems: 'center'}}>
<Text style={styles.stepperTxt}>Create Habit</Text>
</Box>
<IconCircleBack
onPress={() => setHabitNavigation(0)}
style={{...styles.iconBack, top: '2.2%'}}
/>
<Box style={styles.choosenBox}>
<Box
style={styles.choosenButton}>
<Text style={{fontSize: 15, color: '#5D535C'}}>
{chooseSpan.but}
</Text>
</Box>
{chooseButton !== undefined ? (
<Box
style={styles.choosenButtonDynamic}>
<Text style={{fontSize: 15, color: '#5D535C'}}>
{techniques}
</Text>
</Box>
) : (
''
)}
</Box>
<Box style={{height: '6%', marginTop: '2%'}}>
<Text style={styles.headTxt}>Choose a technique</Text>
<Text
style={styles.subHeading}>
Create a habit from any one of your susbcribed techniques
</Text>
</Box>
<Box style={{height: 1050}}>
<Box style={{alignItems: 'center'}}>
{techniqueChooser.map((data, i) => {
return (
<TouchableHighlight
key={i}
underlayColor={'none'}
onPress={() => {
setChooseButton(i), setTechniques(data.button);
}}
style={styles.cardTechniques}>
<>
{chooseButton === i ? <IconCheck style={{position:'absolute',right:10,bottom:"10%",zIndex:1}} /> : ""}
<Image
style={styles.imageOptimism}
resizeMethod="scale"
resizeMode="cover"
source={data.src}
/>
<Image
style={{
...styles.imageBackdrop,
display: `${chooseButton === i ? 'none' : 'flex'}`,
}}
resizeMethod="scale"
resizeMode="cover"
source={require('../../../assets/images/techniqueBackgrounds/backdrop.png')}
/>
<Box
style={styles.buttonTechnique}>
<Text
style={{
fontSize: 14,
fontWeight: 'bold',
color: '#5D535C',
}}>
{data.button}
</Text>
</Box>
</>
</TouchableHighlight>
);
})}
</Box>
</Box>
</ScrollView>
<Box
style={{
position: 'absolute',
bottom: '3%',
width: '100%',
alignItems: 'center',
}}>
<Button
isDisabled={chooseButton !== undefined ? false : true}
style={{
...styles.button2,
backgroundColor: `${
chooseButton !== undefined ? '#36A2D0' : '#6D7A82'
}`,
}}
isLoadingText="Continue"
spinnerPlacement="end"
onPress={() =>{techniques === "Meditation" ? setHabitNavigation(4) : techniques === 'Breathe' ? setHabitNavigation(6) : setHabitNavigation(3)}}>
<MaterialIcons
name="arrow-forward-ios"
style={{
fontSize: 20,
color: `${chooseButton !== undefined ? 'white' : 'black'}`,
}}
/>
</Button>
</Box>
</Box>
</>
);
}
Instead of setting individual id to your state, you add your id to an array then set that array to your state.
onPress={() => {
let newArray = [...chooseButton, i];
setChooseButton(newArray),
setTechniques(data.button);
}}
You then use that array to conditionally render your IconCheck by checking if the id exists in the chooseButton array.
My app displays images and other info getting data from a JSON, and I want to set a blurRadius on the selected image when the unblur function is called.
My code is the following:
const [blur, setBlur] = useState(160);
const unblur = () => {
if(blur == 160){
setBlur(0);
}
}
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<>
<Text style={{ textAlign: "left", color: 'white', fontSize: 24 }}>
<Image style={{ alignSelf: "center" }} source={{uri: item.profile_picture, width: 48, height: 48}} />
{item.username}
</Text>
<TouchableOpacity onPress={() => unblur()}>
<Image style={{ alignSelf: "center" }} blurRadius={blur} source={{uri: item.picture, width: 400, height: 320}} />
</TouchableOpacity>
<Text style={{ textAlign: "left", color: 'white', fontSize: 24 }}>
ID {item.id}
</Text>
<Text>
{'\n'}{'\n'}
</Text>
</>
)}
/>
)}
I want to change the {blur} value for a given image when I tap the TouchableOpacity component of the image I want to unblur. Right in this moment when I tap an image, all the images in the list are getting unblurred.
You should add the blur values inside your items like this. Create a new components called Items. Then, add the blur state inside it. (not inside Main).
const Main = () => {
if (isLoading) {
return;
<ActivityIndicator />;
}
return (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => <Item item={item} />}
/>
);
};
const Item = ({ item }) => {
const [blur, setBlur] = useState(160);
const unblur = () => {
if (blur == 160) {
setBlur(0);
}
};
return (
<>
<Text style={{ textAlign: "left", color: "white", fontSize: 24 }}>
<Image
style={{ alignSelf: "center" }}
source={{ uri: item.profile_picture, width: 48, height: 48 }}
/>
{item.username}
</Text>
<TouchableOpacity onPress={() => unblur()}>
<Image
style={{ alignSelf: "center" }}
blurRadius={blur}
source={{ uri: item.picture, width: 400, height: 320 }}
/>
</TouchableOpacity>
<Text style={{ textAlign: "left", color: "white", fontSize: 24 }}>
ID {item.id}
</Text>
<Text>
{"\n"}
{"\n"}
</Text>
</>
);
};
Also, may I suggest you can use 'onPressIn'. That way, image will unblur when the finger tap the image, not press the image. But that was your decision.
I'm newbie in React-native and I'm confused on how can I pass the parameter to another js file when returning a View, The second problem , The code I used below is when returning home the previous page(login) didn't close or gone and the home didn't view properly. I'm aware using react-nativigation but it's hard for me to implement but is there any other way to direct login when it loads? please need some help for this , here's my code,
Login.js After login from googlesignin when the state loaded it goes to another activity
import { Home } from "../screens"
render() {
return (
<View style={styles.container}>
<GoogleSigninButton
style={{ width: 222, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={this.signIn}
/>
{this.state.loaded ?
<View style={{ width: 160, marginTop: 10 }}>
{renderLogin(this)} //return some value
</View>
: <Text>Not signIn</Text>}
</View>
);
}
}
function renderLogin(ts) {
return (
<Home /> // i want to pass value to home js example: 'ts.state.userGoogleInfo.user.photo'
)
}
Whole code in Login.js
import React, { Component } from 'react';
import { View, StyleSheet, ToastAndroid, Button, Text, Image } from "react-native";
import { Home } from "../screens"
import {
GoogleSignin,
GoogleSigninButton,
statusCodes,
} from '#react-native-community/google-signin';
GoogleSignin.configure({
webClientId: '2622122222248-3v21124124124124.apps.googleusercontent.com',
offlineAccess: true, // if you want to access Google API on behalf
});
class Login extends Component {
constructor(props) {
super(props)
this.state = {
userGoogleInfo: {},
loaded: false
}
}
static navigationOptions = {
title: 'Login',
};
signIn = async () => {
try {
console.log("Processing");
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
this.setState({
userGoogleInfo: userInfo,
loaded: true
})
console.log(this.state.userGoogleInfo);
console.log(this.state.userGoogleInfo.user.name)
console.log(this.state.userGoogleInfo.user.email)
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log("e 1");
} else if (error.code === statusCodes.IN_PROGRESS) {
console.log("e 2");
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log("e 3");
} else {
console.log(error.message);
}
}
};
render() {
return (
<View style={styles.container}>
<GoogleSigninButton
style={{ width: 222, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={this.signIn}
/>
{this.state.loaded ?
<View style={{ width: 160, marginTop: 10 }}>
{renderLogin(this)}
</View>
: <Text>Not signIn</Text>}
</View>
);
}
}
function renderLogin(ts) {
return (
<Home />
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000000',
padding: 15,
},
buttons: {
width: 20
}
});
export default Login;
Home.js
import React from 'react';
import {
StyleSheet,
View,
Text,
ScrollView,
FlatList,
TouchableOpacity,
Image,
ImageBackground,
LogBox
} from 'react-native';
import { PriceAlert, TransactionHistory } from "../components"
import { dummyData, COLORS, SIZES, FONTS, icons, images} from '../constants';
const Home = ({ navigation }) => {
const [trending, setTrending] = React.useState(dummyData.trendingCurrencies)
const [transactionHistory, setTransactionHistory] = React.useState(dummyData.transactionHistory)
function renderHeader(){
const renderItem = ({item, index}) =>(
<TouchableOpacity
style={{
width:155,
paddingVertical:SIZES.padding,
paddingHorizontal:SIZES.padding,
marginLeft: index == 0 ? SIZES.padding : 0,
marginRight: SIZES.radius,
borderRadius: 15,
backgroundColor: COLORS.white
}}
onPress={() => navigation.navigate("CryptoDetail", {currency:item})}
>
{/* Currency*/}
<View style={{ flexDirection:'row'}}>
<View>
<Image
source={item.image}
resizeMode="cover"
style={{
marginTop: 5,
width: 25,
height: 25
}}
/>
</View>
<View style={{marginLeft: SIZES.base}}>
<Text style={{...FONTS.h3}}>{item.currency}</Text>
<Text style={{ color:COLORS.gray, ...FONTS.body3 }}></Text>
</View>
</View>
{/* value*/}
{/* <View style={{ marginTop:SIZES.radius}}> */}
{/* <Text style={{...FONTS.h6}}>₱{item.amount}</Text> */}
{/* <Text style={{color: item.type =="I" ? COLORS.green : COLORS.red, ...FONTS.h5}}>₱{item.amount}</Text> */}
{/* </View> */}
</TouchableOpacity>
)
return(
<View
style={{
width: "100%",
height: 210,
...styles.shadow
}}
>
<ImageBackground
source={images.banner}
resizeMode="cover"
style={{
flex: 1,
alignItems:'center'
}}
>
{/* Header Bar */}
<View
style={{
marginTop:SIZES.padding *1,
width: "100%",
alignItems: "flex-end",
paddingHorizontal: SIZES.padding
}}
>
<TouchableOpacity
style={{
width: 20,
height: 20,
alignItems: "center",
justifyContent:"center"
}}
onPress={() => console.log("Notification on pressed")}
>
<Image
source={icons.notification_white}
resizeMode="contain"
style={{flex: 1}}
/>
</TouchableOpacity>
</View>
{/* Balance */}
<View
style={{
alignItems: 'center',
justifyContent:'center'
}}
>
<Text style={{ color: COLORS.white, ...FONTS.h3}}>Available Balance</Text>
<Text style={{ marginTop:SIZES.base, color:COLORS.white, ...FONTS.h2}}>₱{dummyData.portfolio.balance}</Text>
<Text style={{color:COLORS.white, ...FONTS.body5}}>{dummyData.portfolio.changes} Last 24 hours</Text>
</View>
{/* Trending */}
<View
style={{
position:'absolute',
bottom: "-30%"
}}
>
<Text style={{ marginLeft:SIZES.padding,
color: COLORS.white, ...FONTS.h3 }}>Dashboard</Text>
<FlatList
contentContainerStyle={{marginTop:SIZES.base}}
data={trending}
renderItem={renderItem}
keyExtractor={item => `${item.id}`}
horizontal
showsHorizontalScrollIndicator={false}
/>
</View>
</ImageBackground>
</View>
)
}
function renderAlert(){
return (
<PriceAlert/>
)
}
function renderNotice(){
return (
<View
style={{
marginTop:SIZES.padding-6,
marginHorizontal: SIZES.padding,
padding: 12,
borderRadius:SIZES.radius,
backgroundColor:COLORS.secondary,
...styles.shadow
}}
>
<Text style={{color:COLORS.white, ...FONTS.h4}}>Announcement:</Text>
<Text style={{marginTop:SIZES.base, color:COLORS.white, ...FONTS.body4, lineHeight:18}}>We offer you an application to guide and track your data.
Learn how to use this application by reading instructions and guide.
</Text>
<TouchableOpacity
style={{
marginTop:SIZES.base
}}
onPress={()=> console.log("Learn More")}
>
<Text style={{ textDecorationLine: 'underline',
color:COLORS.green, ...FONTS.h4}}>Learn more
</Text>
</TouchableOpacity>
</View>
)
}
function renderTransactionHistory(){
return (
<TransactionHistory
customContainerStyle={{ ...styles.shadow}}
history={transactionHistory}
/>
)
}
return (
<ScrollView>
<View style={{ flex:1, paddingBottom:130 }}>
{renderHeader()}
{renderAlert()}
{renderNotice()}
{renderTransactionHistory()}
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
shadow: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.30,
shadowRadius: 4.65,
elevation: 8,
}
})
export default Home;
Apps.js
import React from 'react';
import { Transaction, TevDetail, Login } from "./screens";
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer } from '#react-navigation/native';
import SplashScreen from 'react-native-splash-screen';
import Tabs from "./navigation/tabs";
const Stack = createStackNavigator();
const App = () => {
React.useEffect(() => {
SplashScreen.hide()
}, [])
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false
}}
initialRouteName={'Login'}
>
<Stack.Screen
name="Home"
component={Tabs}
/>
<Stack.Screen
name="TevDetail"
component={TevDetail}
/>
<Stack.Screen
name="Transaction"
component={Transaction}
/>
<Stack.Screen
name="Login"
component={Login}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default App;
The code below creates a card, within this card I want to load the url from the card and make a webview appear using the 'react-native-webview' import.
import {View, Linking, TouchableNativeFeedback} from 'react-native';
import {Text, Button, Card, Divider} from 'react-native-elements';
import moment from 'moment';
import {WebView} from 'react-native-webview';
export default class DataItem extends React.Component {
render() {
const {title, description, publishedAt, source, urlToImage, url} =
this.props.article;
const {noteStyle, featuredTitleStyle} = styles;
const time = moment(publishedAt || moment.now()).fromNow();
return (
<TouchableNativeFeedback
useForeground
onPress={() => <WebView source={{uri: url}} style={{marginTop: 20}} />}>
<Card>
<Text style={{fontWeight: 'bold'}}> {title || 'YEET'} </Text>
<Divider style={{backgroundColor: '#dfe6e9', margin: 5}} />
<Card.Image source={{uri: urlToImage}} />
<Text style={{marginBottom: 10}}>{description || 'Read More..'}</Text>
<Divider style={{backgroundColor: '#dfe6e9'}} />
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={noteStyle}>{source.name.toUpperCase()}</Text>
<Text style={noteStyle}>{time}</Text>
</View>
</Card>
</TouchableNativeFeedback>
);
}
}
I assume you are trying to show a webview when the card press. The problem I see in your code is that you are trying to return a component on Touchable onPress which is not a correct way. You have to keep the state for that like when you press the card state goes active and shows the webview.
Try This
import { View, Linking, TouchableNativeFeedback } from 'react-native';
import { Text, Button, Card, Divider } from 'react-native-elements';
import moment from 'moment';
import { WebView } from 'react-native-webview';
export default class DataItem extends React.Component {
state = {
showWebview: false,
};
render() {
const {
title,
description,
publishedAt,
source,
urlToImage,
url,
} = this.props.article;
const { noteStyle, featuredTitleStyle } = styles;
const time = moment(publishedAt || moment.now()).fromNow();
return (
<View>
<TouchableNativeFeedback
useForeground
onPress={() => {
this.setState({ showWebview: true });
}}
>
<Card>
<Text style={{ fontWeight: 'bold' }}> {title || 'YEET'} </Text>
<Divider style={{ backgroundColor: '#dfe6e9', margin: 5 }} />
<Card.Image source={{ uri: urlToImage }} />
<Text style={{ marginBottom: 10 }}>
{description || 'Read More..'}
</Text>
<Divider style={{ backgroundColor: '#dfe6e9' }} />
<View
style={{ flexDirection: 'row', justifyContent: 'space-between' }}
>
<Text style={noteStyle}>{source.name.toUpperCase()}</Text>
<Text style={noteStyle}>{time}</Text>
</View>
</Card>
</TouchableNativeFeedback>
{this.state.showWebView && ( // it will show webview whew showWebview is true.
<WebView source={{ uri: url }} style={{ marginTop: 20 }} />
)}
</View>
);
}
}
Hey guys I'm having an issue with navigation:
I select an item from the menuoption
I then call the 'testFunction'
Function will call an alert function so it is working
When I add the navigation part I get the error below:
undefined is not an object (evaluating '_this2.props.navigation.navigate')
Here is the import code:
import { NavigationScreenProp } from "react-navigation";
Here is where it is added to props:
interface NotificationDropdownProps {
navigation: NavigationScreenProp<any,any>
}
Here is where code is rendered:
class NotificationDropdown extends React.Component<Props, NotificationDropdownState> {
testFunction = () => {
this.props.navigation.navigate('Leagues')
};
<MenuOption
onSelect={() =>
{
if(notification.type == INotificationType.SYSTEM){
this.testFunction()
}
}
}
customStyles={{ optionWrapper: { padding: 0, margin: 0, zIndex: 100000000 } }}>
<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 style={styles.notificationData} >
<Text style={styles.notificationTxt}>{notification.text}</Text>
<Text style={styles.notificationDate}>{this.getDate(new Date(notification.dateCreated))}</Text>
</View>
</View>
</MenuOption>
Render:
render() {
return (
<Menu
renderer={Popover} rendererProps={{ placement: 'bottom', preferredPlacement: 'bottom' }}
opened={this.state.opened}
onBackdropPress={() => this.togglePopup()}
onClose={() => {
this.setState({ showEmpty: true });
// Store.dispatch(SetNotificationSeen());
}}
onOpen={() => {
Store.dispatch(SetNumberSeen(this.props.notifications.length));
}}
>
<MenuTrigger onPress={() => this.togglePopup()}>
<View style={{ padding: 10 }}>
<Icon name='ios-notifications-outline' color={'rgba(0,0,0,0.6)'} size={25} /></View>
</MenuTrigger>
<MenuOptions customStyles={{
optionsContainer: {
width: Dimensions.get('window').width * 0.75,
zIndex: 100000000,
elevation: 8,
borderRadius: 20
}
}}>
<View style={{ padding: 10 }}>
<Text style={{
fontSize: 20,
marginLeft: 10,
color: 'rgba(0,0,0,0.6)',
fontWeight: 'bold',
paddingBottom: 5
}}>Notifications</Text>
{this.props.notifications.length > 0 ? <FlatList
contentContainerStyle={{ borderRadius: 10 }}
// only allow 5 notifications
data={this.props.notifications.slice(0,5)}
renderItem={({ item }) => this.renderNotification(item)}
style={{ maxHeight: 200, zIndex: 5 }}
keyExtractor={this.keyExtractor}
/> : <Text style={styles.noNotifications}>No Notifications!</Text>}
</View>
</MenuOptions>
</Menu>
);
}
What am I missing? any help is welcome
Here is where the is called from the header.tsx
<View style={styles.icon}>
<NotificationDropdown />
{this.props.numberSeen < this.props.notificationCount ? <Badge value={this.props.notificationCount - this.props.numberSeen > 99 ? '99+' : this.props.notificationCount - this.props.numberSeen}
status="error" containerStyle={styles.badge} /> : null}
</View>
Ok so it seems that NavigationDropDown doesn't have the navigation props.
What you need is to pass the navigation props explicitly as it is not a screen component.
in the headercomponent.tsx
<View style={styles.icon}>
<NotificationDropdown navigation={this.props.navigation} />
{this.props.numberSeen < this.props.notificationCount ? <Badge value={this.props.notificationCount - this.props.numberSeen > 99 ? '99+' : this.props.notificationCount - this.props.numberSeen}
status="error" containerStyle={styles.badge} /> : null}
</View>
I assume that you have the navigation props in the headercomponent.tsx