Fetch data from realtime database firebase in react native? - arrays

I already have data in my realtime database. I can also fetch it successfully. Now what I need to do is output it in a tinder-like card view. I am currently outputting data using a 'Demo' file which exports a hard-coded array that contains sample information of some users. Using the demo array, the card output is working. But when I fetch data from firebase and store it in an array named items[], nothing is displayed on my output screen. My code is as follows:
Home Screen
import React from 'react';
import { View, ImageBackground } from 'react-native';
import CardStack, { Card } from 'react-native-card-stack-swiper';
import City from '../components/City';
import Filters from '../components/Filters';
import CardItem from '../components/CardItem';
import styles from '../assets/styles';
import Demo from '../assets/demo';;
import {db} from '../config/config';
class Home extends React.Component {
constructor (props) {
super(props);
this.state = ({
items: []
});
}
componentWillMount() {
var items = [];
db.ref('cards').once('value', (snap) => {
snap.forEach((child) => {
let item = child.val();
item.id = child.key;
items.push({
pet_name: child.val().pet_name,
pet_gender: child.val().pet_gender,
pet_age: child.val().pet_age,
pet_breed: child.val().pet_breed,
photoUrl: child.val().photoUrl,
});
});
//console.log(items)
this.setState({ items: items });
console.log(items);
});
}
render() {
return (
<ImageBackground
source={require('../assets/images/bg.png')}
style={styles.bg}
>
<View style={styles.containerHome}>
<View style={styles.top}>
<City />
<Filters />
</View>
<CardStack
loop={true}
verticalSwipe={false}
renderNoMoreCards={() => null}
ref={swiper => {
this.swiper = swiper
}}
>
{Demo.map((item, index) => (
<Card key={index}>
<CardItem
image={item.image}
name={item.name}
description={item.description}
actions
onPressLeft={() => this.swiper.swipeLeft()}
onPressRight={() => this.swiper.swipeRight()}
/>
</Card>
))}
</CardStack>
</View>
</ImageBackground>
)
}
}
export default Home;
Demo Data
module.exports = [
{
id: 3,
name: 'whatever',
status: 'Online',
match: '78',
description:
'Full-time Traveller. Globe Trotter. Occasional Photographer. Part time Singer/Dancer.',
message:
'I will go back to Gotham and I will fight men Iike this but I will not become an executioner.',
image: require('./images/01.jpg')
},
{
id: 2,
name: 'Clementine Bauch',
match: '93',
description:
'Full-time Traveller. Globe Trotter. Occasional Photographer. Part time Singer/Dancer.',
status: 'Offline',
message: "Someone like you. Someone who'll rattle the cages.",
image: require('./images/02.jpg')
}
];
fetching data:
import {db} from '../config/config';
var items = [];
db.ref('cards').once('value', (snap) => {
snap.forEach((child) => {
let item = child.val();
item.id = child.key;
items.push({
pet_name: child.val().pet_name,
pet_gender: child.val().pet_gender,
pet_age: child.val().pet_age,
pet_breed: child.val().pet_breed,
photoUrl: child.val().photoUrl,
});
});
//console.log(items)
for (var i in items){
console.log(items[i])
}
});
export var items;
I want to use my items[] array instead of the Demo hard-coded array. How do I do this?
The output of items[] array:
Array [
Object {
"pet_age": "11",
"pet_breed": "golden retriever",
"pet_gender": "male",
"pet_name": "dawn",
"photoUrl": "picture",
},
Object {
"pet_age": "7",
"pet_breed": "German",
"pet_gender": "Male",
"pet_name": "Rambo",
"photoUrl": "https://firebasestorage.googleapis.com/v0/b/woofmatix-50f11.appspot.com/o/pFkdnwKltNVAhC6IQMeSapN0dOp2?alt=media&token=36087dae-f50d-4f1d-9bf6-572fdaac8481",
},
]
CardItem component:
import React from 'react';
import styles from '../assets/styles';
import { Text, View, Image, Dimensions, TouchableOpacity } from 'react-native';
import Icon from './Icon';
const CardItem = ({
actions,
description,
image,
matches,
name,
pet_name,
pet_gender,
pet_age,
onPressLeft,
onPressRight,
status,
variant
}) => {
// Custom styling
const fullWidth = Dimensions.get('window').width;
const imageStyle = [
{
borderRadius: 8,
width: variant ? fullWidth / 2 - 30 : fullWidth - 80,
height: variant ? 170 : 350,
margin: variant ? 0 : 20
}
];
const nameStyle = [
{
paddingTop: variant ? 10 : 15,
paddingBottom: variant ? 5 : 7,
color: '#363636',
fontSize: variant ? 15 : 30
}
];
return (
<View style={styles.containerCardItem}>
{/* IMAGE */}
<Image source={image} style={imageStyle} />
{/* MATCHES */}
{matches && (
<View style={styles.matchesCardItem}>
<Text style={styles.matchesTextCardItem}>
<Icon name="heart" /> {matches}% Match!
</Text>
</View>
)}
{/* NAME */}
<Text style={nameStyle}>{name}</Text>
{/* DESCRIPTION */}
{description && (
<Text style={styles.descriptionCardItem}>{description}</Text>
)}
{/* STATUS */}
{status && (
<View style={styles.status}>
<View style={status === 'Online' ? styles.online : styles.offline} />
<Text style={styles.statusText}>{pet_age}</Text>
</View>
)}
{/* ACTIONS */}
{actions && (
<View style={styles.actionsCardItem}>
<View style={styles.buttonContainer}>
<TouchableOpacity style={[styles.button, styles.red]} onPress={() => {
this.swiper.swipeLeft();
}}>
<Image source={require('../assets/red.png')} resizeMode={'contain'} style={{ height: 62, width: 62 }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.orange]} onPress={() => {
this.swiper.goBackFromLeft();
}}>
<Image source={require('../assets/back.png')} resizeMode={'contain'} style={{ height: 32, width: 32, borderRadius: 5 }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.green]} onPress={() => {
this.swiper.swipeRight();
}}>
<Image source={require('../assets/green.png')} resizeMode={'contain'} style={{ height: 62, width: 62 }} />
</TouchableOpacity>
</View>
</View>
)}
</View>
);
};
export default CardItem;

Related

How to do a loop for cards

how do i do a loop for 10 cards? Cant find any solution anywhere.
I need it to output cards with some info which ill specify later. I am new to React Native and got no idea what Im doing. It worked when ive written return into the loop, but it returned just one card (better than none I guess).
import * as React from 'react';
import { StyleSheet, ScrollView, View, Text, Image } from 'react-native';
import { Card, CardTitle, CardContent, CardAction, CardButton, CardImage } from 'react-native-material-cards'
export default function Primary({ navigation })
{
return(
<ScrollView style=
{{
flex: 1,
}}>
<View>
<Text style={{ fontSize: 26, fontWeight: 'bold' }}>
Hlavni
</Text>
<Text>Ahojda</Text>
</View>
<Text>Swag</Text>
<KartyLoop/>
</ScrollView>
);
}
const KartyLoop = () => {
var swag[];
for (i=0; i<5; i++)
{
<View>
<Card style={{borderRadius: 25}}>
<CardTitle
title="This is a title"
subtitle="This is subtitle"
/>
<CardContent text="Your device will reboot in few seconds once successful, be patient meanwhile" />
<CardAction
separator={true}
inColumn={false}>
<CardButton
onPress={() => {}}
title="Push"
color="blue"
/>
<CardButton
onPress={() => {}}
title="Later"
color="blue"
/>
</CardAction>
</Card>
</View>
}
return();
}
When rendering a list of components in react native, you need to put them in some sort of list.
Try wrapping the code inside your <View> with <Flatlist>
Docs: https://reactnative.dev/docs/flatlist
Full example from docs:
import React from 'react';
import { SafeAreaView, View, FlatList, StyleSheet, Text, StatusBar } from 'react-native';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight || 0,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
export default App;

How to get data from checkbuttons to a list in React Native?

I am a beginner with React Native, so I need help with following:
I am programming an App, where you can choose between two radio button groups. To every radio button should belong data (key and value pairs, in categories). If choose two options and afterwards press the butto "Create my plan" it should randomly choose some entries of the key value kategories and create a flatlist from it.
My problem is, that I dont know how I can pass data bewteen two classes or if there is an other way to realize what I picture.
Please do not be put off by the amount of code, if you copy it and paste it into an empty project, it works immediately and you will understand my question.
I am very grateful for your help.
Here is my Code:
import React, { Component, useState, createContext } from 'react';
import { StyleSheet, FlatList, Text, Dimensions, Button, View, Image, ScrollView, TouchableOpacity, Animated } from 'react-native';
import { registerRootComponent } from 'expo';
import { RadioButton } from 'react-native-paper';
import 'react-native-gesture-handler';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
//Ein StackNavigator-Objekt wird erzeugt
const Stack = createStackNavigator();
class Auswahl extends React.Component {
state = {
value1: 'first',
value2: 'first',
value3: 'first',
checked: 'agnostic'
};
render() {
return (
<View style={{alignItems:"center", flex:1, flexDirection:'column' }}>
<View style={{position:'absolute', alignItems:"center", flex:1, flexDirection:'column'}}>
<Text style={{ marginTop:50, marginBottom:10 }}>Auf welchem Niveau praktizierst du?</Text>
<View style={{flex: 1, flexDirection: 'column', marginBottom: 20}}>
<RadioButton.Group
onValueChange={value1 => this.setState({ value1 })}
value={this.state.value1}>
<Text>Anfgänger</Text>
<RadioButton.Android value="first" />
<Text>Geübt</Text>
<RadioButton.Android value="second" />
<Text>Eingeschränkt</Text>
<RadioButton.Android value="third" />
</RadioButton.Group>
<Text style={{ marginBottom: 10 }}>Möchtest du einen Fokus setzten?</Text>
<RadioButton.Group
onValueChange={value2 => this.setState({ value2 })}
value={this.state.value2}>
<Text>Dehnung</Text>
<RadioButton.Android value="first" />
<Text>Hüftöfner</Text>
<RadioButton.Android value="second" />
<Text>Energie</Text>
<RadioButton.Android value="third" />
</RadioButton.Group>
<Button style={{margin:10, padding:10}} title="Erstelle meinen Plan" onPress={() =>
this.props.navigation.navigate('UebungenAnzeigen') }/>
</View>
<View/>
</View>
</View>
);
}
}
class UebungenAnzeigen extends React.Component {
constructor(props){
super(props);
this.state = {
data:[
{
"name": "Herabschauender Hund",
"kategorie":"Basic",
"nummer" : "0",
"erklaerung": "Steißbein zur Decke | Rücken gerade | Kopf in Verlängerung der Wirbelsäule",
"photo": "",
"dauer": 30
},
{
"name": "Katze",
"nummer" : "2",
"erklaerung": "Steißbein zur Decke | Rücken gerade | Kopf in Verlängerung der Wirbelsäule",
"photo": "",
"dauer": 20
},
]
}
}
render() {
function Item({ item }) {
const [shouldShow, setShouldShow] = useState(true);
return (
<View style={styles.container}>
{shouldShow ? (
null
) :
<View style={stylesUebungAnzeigen.uebung}>
<Text>Details</Text>
<Text style={{marginTop: 20 }}>{item.name}</Text>
<TouchableOpacity style={{marginTop: 100, color:'green'}} onPress= {() => setShouldShow(!shouldShow)}>Zurück zur Übersicht</TouchableOpacity>
</View>
}
<View style={stylesUebungAnzeigen.listItem}>
<Image source={item.photo} style={{width:90, height:60, borderRadius:10}} />
<View style={{alignItems:"center",flex:1}}>
<Text style={{fontWeight:"bold"}}>{item.name}</Text>
<Text>{item.dauer}</Text>
</View>
<TouchableOpacity onPress={() => setShouldShow(!shouldShow)} style={{height:50,width:50,
justifyContent:"center", alignItems:"center"} }>
<Text style={{color:"green", fontWeight:"bold"}}>Hilfestellung?</Text>
</TouchableOpacity>
</View>
</View>
);
}
return (
<View>
<View style={stylesUebungAnzeigen.container2}>
<FlatList style={{flex:1}}
data={this.state.data}
renderItem={({ item }) => <Item item= {item}/>}
keyExtractor={item => item}
/>
</View>
</View>
);
}
}
const stylesUebungAnzeigen = StyleSheet.create ({
buttons: {
flex: 1,
alignSelf:"center",
height: 10,
width: 30
},
uebung:{
fex:1,
alignSelf:"center",
justifyContent:"center",
height: 911,
width: 318,
borderColor:'grey',
backgroundColor: 'white'
},
text:{
flex:1,
justifyContent: 'center'
},
container2: {
flex: 1,
backgroundColor: '#F7F7F7',
marginTop:60
},
title: {
fontSize: 14,
backgroundColor: '#FFF',
marginTop: 10
},
listItem:{
margin:10,
padding:10,
backgroundColor:"#FFF",
width:"80%",
flex:1,
alignSelf:"center",
flexDirection:"row",
borderRadius:2
},
});
// geht nicht umzubennen nochmal gucken
const styles = StyleSheet.create({
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
container:{
flex: 1,
marginTop: 20,
},
group: {
flexDirection: 'row',
justifyContent: 'space-around',
},
SeparatorLine :{
backgroundColor : '#fff',
width: 1,
height: 40
},
elementsContainer: {
backgroundColor: '#ecf5fd',
}
});
export default class Willkommen extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Auswahl"
component={Auswahl}
/>
<Stack.Screen
name="UebungenAnzeigen"
component={UebungenAnzeigen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
registerRootComponent(Willkommen);
I don't completely understand the question. Because its just if else to check which one is selected (according to your schema).
How you will pass values from one screen to another is as follows.
<Button style={{margin:10, padding:10}} title="Erstelle meinen Plan" onPress={() =>
this.props.navigation.navigate('UebungenAnzeigen',{
data : {value1, value2 ,...etc}}) }/>
And on next screen you can receive that data using following code.
let data = props.route.params?.data;
console.log(data.value1, data.value2)

API image not being displayed in list

I know there are several questions with this issue but mine is different.
I trying to display an image in my Flatlist card that is coming from an API. However it is not showing up.
BUT...when I display this image in another part of my code (in an Autocomplete list) using the same code basically, it works. Also, when I try an url from an image on the Web, it displays inside the flatlist correctly
Here's my Flatlist code:
<FlatList
data={this.state.myGamesArray}
renderItem={({ item }) => (
<Card>
<CardItem>
<View>
<Image
style={styles.gameImage}
source={{uri: item.background_image}}
/>
</View>
</CardItem>
<CardItem>
<View>
<Text style={styles.usergameText}>
{item}
</Text>
</View>
</CardItem>
</Card>
)}
keyExtractor={(item,index) => index.toString()}
/>
Here is my Autocomplete code in which I use the same image bracket-thingy
<View style={styles.iconContainer} >
<TouchableOpacity onPress={() => this.setState({ query: item.name})}
style={styles.autocompleteList} >
<View>
<Image
style={styles.gameImage}
source={{uri: item.background_image}}
/>
</View>
<Text style={styles.gameText}>
{item.name}
</Text>
</TouchableOpacity>
</View>
I ran console.item(item.background_image) both inside the Flatlist(first snippet) and the Autocomplete list (Second snippet). The first shows 'undefined' and the second it shows all the URIs
App.js full code:
/*This is an example of AutoComplete Input/ AutoSuggestion Input*/
import React, { Component } from 'react';
//import react in our code.
import { StyleSheet, Text, TouchableOpacity, View, Image, FlatList, Alert, TouchableWithoutFeedback, Keyboard } from 'react-native';
//import all the components we are going to use.
import Autocomplete from 'react-native-autocomplete-input';
import { Button, List, Container, ListItem, Card, CardItem, Header, Item } from 'native-base';
import { Entypo } from '#expo/vector-icons'
//import Autocomplete component
//const API = 'https://api.rawg.io/api/games?page=1';
//Demo base API to get the data for the Autocomplete suggestion
class App extends Component {
constructor(props) {
super(props);
//Initialization of state
//films will contain the array of suggestion
//query will have the input from the autocomplete input
this.state = {
myGamesArray: [],
games: [],
query: ' ',
};
}
componentDidMount() {
//First method to be called after components mount
//fetch the data from the server for the suggestion
fetch('https://api.rawg.io/api/games?page=1&platforms=18', {
"method": "GET",
"headers": {
"x-rapidapi-host": "rawg-video-games-database.p.rapidapi.com",
"x-rapidapi-key": "495a18eab9msh50938d62f12fc40p1a3b83jsnac8ffeb4469f"
}
})
.then(res => res.json())
.then(json => {
const { results: games } = json;
this.setState({ games });
//setting the data in the games state
});
}
findGame(query) {
let i;
//method called everytime when we change the value of the input
if (query === '') {
//if the query is null then return blank
return [];
}
const { games } = this.state;
//making a case insensitive regular expression to get similar value from the film json
const regex = new RegExp(`${query.trim()}`, 'i');
//return the filtered game array according the query from the input
return games.filter(game => game.name.search(regex) >= 0);
}
AddItemsToArray = () => {
var i
//verifica se input esta vazio
if (this.state.query === '') {
return Alert.alert('Voce não selecionou um jogo')
}
//VERIFY IF GAME IS IN THE ARRAY
for (i = 0; i < this.state.games.length - 1; i++) {
if (this.state.query !== this.state.games[i].name) {
if (i === this.state.games.length - 2) {
return Alert.alert('Este jogo nao existe')
}
else {
continue
}
} else {
break
}
}
//verifica repetido
if (this.state.myGamesArray.includes(this.state.query)) {
return Alert.alert('Este jogo já foi adicionado')
}
else {
//Adding Items To Array.
this.setState(prevState => {
const { myGamesArray, query } = prevState;
return {
myGamesArray: [...myGamesArray, query.toString()],
};
},
// Use setState callback to alert with the updated state
);
}
}
render() {
const { query } = this.state;
const games = this.findGame(query);
const comp = (a, b) => a.toLowerCase().trim() === b.toLowerCase().trim();
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss()
}}
>
<View style={styles.container}>
<View style={styles.listContainer}
>
<FlatList
data={this.state.myGamesArray}
renderItem={({ item }) => (
console.log(item.background_image),
<Card style={{flexDirection:'row',paddingEnd:100}}>
<CardItem cardBody>
<View>
<Image
style={styles.listImage}
source={{uri: item.background_image}}
/>
</View>
</CardItem>
<CardItem>
<View>
<Text style={styles.usergameText}>
{item}
</Text>
<Text style={styles.usergameText}>
Playstation 4
</Text>
</View>
</CardItem>
</Card>
)}
keyExtractor={(item,index) => index.toString()}
/>
</View>
<View>
<Header span
style={styles.header}>
<Autocomplete
inputContainerStyle={{borderColor:'transparent'}}
style={styles.autocompleteInput}
autoCapitalize="none"
autoCorrect={false}
//data to show in suggestion
data={games.length === 1 && comp(query, games[0].name) ? [] : games}
//default value if you want to set something in input
defaultValue={query}
/*onchange of the text changing the state of the query which will trigger
the findGame method to show the suggestions*/
onChangeText={text => this.setState({ query: text })}
placeholder=" Adicione os jogos que você tem"
//This below is the 'list' of autocomplete options
renderItem={({ item }) => (
//you can change the view you want to show in suggestion from here
//I GET ERROR WHEN TRYING TO ERASE (PS4) IN TEXT BOX ***NEED TO CHECK THIS
<View style={styles.iconContainer} >
<TouchableOpacity onPress={() => this.setState({ query: item.name})}
style={styles.autocompleteList} >
<View>
<Image
style={styles.gameImage}
source={{uri: item.background_image}}
/>
</View>
<Text style={styles.gameText}>
`${item.name}`
</Text>
</TouchableOpacity>
</View>
)}
/>
</Header>
</View>
<TouchableOpacity
style={styles.addButton}
onPress={() => this.AddItemsToArray()}
>
<Entypo name="plus" size={50} color="#fff" />
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#fff',
flex: 1,
},
autocompleteInput: {
borderWidth: 1,
backgroundColor: "#fff",
borderColor: '#7843FF',
height: 50,
marginTop: 70,
borderRadius:10,
},
autocompleteList: {
flex:1,
flexDirection: 'row',
borderWidth:0.5,
borderColor: '#7843FF',
paddingVertical: 5,
paddingRight: 60,
},
listContainer: {
flex: 1,
position: 'absolute',
left: 10,
right: 10,
top:150,
flexDirection:'column',
justifyContent: 'center',
borderColor: '#7843FF',
},
gameText: {
fontSize: 15,
marginLeft: 10,
marginRight:30,
marginVertical:10,
color: '#000',
textAlign: 'left',
justifyContent: 'center'
},
usergameText: {
fontSize:15,
textAlign: 'left',
alignSelf:'stretch',
color: '#000',
},
gameImage: {
flex: 3,
height: 60,
width: 60,
marginLeft:10,
borderRadius: 100,
},
listImage: {
flex: 3,
height: 110,
width: 90,
marginLeft:0,
},
addButton: {
height:50,
width: 50,
position: 'absolute',
left: 371,
top: 71,
backgroundColor: '#7843FF',
borderTopRightRadius: 10,
borderBottomRightRadius:10,
},
usergameImage: {
height: 100,
width: 100,
borderRadius: 100,
},
header: {
backgroundColor:'#67E6DC'
}
});
export default App;

React native how to animate view opening up->down

Consider the following component where the user selects an option from a list:
import React, { Component } from "react";
import PropTypes from "prop-types";
import {
View,
Text,
StyleSheet,
Platform,
FlatList,
TouchableNativeFeedback,
TouchableOpacity,
PLatform
} from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
import { colors, metrics } from "../../themes";
const Touchable =
Platform.OS === "android" ? TouchableNativeFeedback : TouchableOpacity;
class MenuSelector extends Component<{
onSelect: () => any,
config: object,
selected: string
}> {
state = {
listOpened: false
};
handlePress = id => {
this.props.onPress(id);
};
handleSelect = id => {
if (this.props.onSelect) this.props.onSelect(id);
this.setState({
listOpened: false
});
};
handleMenu = () => {
this.setState({
listOpened: !this.state.listOpened
});
};
render = () => {
let title = "";
if (this.props.config) {
title = this.props.config[0].title;
if (this.props.selected) {
let found = this.props.config.find(item => {
return item.id === this.props.selected;
});
if (found) title = found.title;
}
}
let top = (
<View style={styles.header}>
<Text style={styles.text}>{title}</Text>
<Touchable>
<Text style={styles.text}>
<Icon
name={"ios-menu"}
size={20}
onPress={this.handleMenu}
/>
</Text>
</Touchable>
</View>
);
let list = null;
if (this.state.listOpened === true) {
list = (
<FlatList
data={this.props.config}
renderItem={({ item }) => (
<Touchable onPress={this.handleSelect}>
<Text style={[styles.text, styles.listItem]}>{item.title}</Text>
</Touchable>
)}
/>
);
}
return (
<View style={styles.container}>
{top}
{list}
</View>
);
};
}
export default MenuSelector;
const styles = StyleSheet.create({
container: {
flex: -1,
flexDirection: "column"
},
header: {
flex: -1,
flexDirection: "row",
justifyContent: "space-between",
padding: 10,
backgroundColor: "blue"
},
text: {
fontSize: 16,
color: "white",
textAlign: "center",
fontWeight: "bold"
},
listItem: {
padding: 10,
backgroundColor: "blue"
}
});
The component is used in the following context:
let config = [
{
title="Option 1",
id="option1"
},
{
title="Option 2",
id="option2"
},
{
title="Option 3",
id="option3"
},
{
title="Option 4",
id="option4"
},
];
return (
<View style={styles.container}>
<MenuSelector
config={config.options}
selected={this.state.mode}
onPress={this.handleButtonListPress}
/>
<FlatList
data={this.props.data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<Text style={styles.text}>{item.name}</Text>
)}
/>
</View>
);
As it is, the <MenuSelector> component appears "at once" on screen. I need to add an sliding effect to <MenuSelector>, "pushing down" the data FlatList when appearing on screen...
On closing, same behaviour, but animating from down to up.
How can I add such animation behaviour to my MenuSelector component ?

Can't pass value as function in React Navite Element Button

I want to display model with the key value from array, but I can't do it, and I don't understand the problem.
this is react native in Expo and I have used react native elements
import React, {Component} from "react";
import { ScrollView, Text, Linking, View, Modal } from "react-native";
import { Card, Button } from "react-native-elements";
import PriceDetail from "./PriceDetail";
const images = [
{
key: 1,
name: "Nathan Anderson",
image: require("../images/1.jpg"),
url: "https://unsplash.com/photos/C9t94JC4_L8"
},
{
key: 2,
name: "Jamison McAndie",
image: require("../images/2.jpg"),
url: "https://unsplash.com/photos/waZEHLRP98s"
},
{
key: 3,
name: "Alberto Restifo",
image: require("../images/3.jpg"),
url: "https://unsplash.com/photos/cFplR9ZGnAk"
},
{
key: 4,
name: "John Towner",
image: require("../images/4.jpg"),
url: "https://unsplash.com/photos/89PFnHKg8HE"
}
];
class Home extends Component {
state = {
selectedItem : null,
mvisible : false
}
modalClosedHandler = () => {
this.setState({
mvisible: false,
selectedItem: null
});
};
productSelectedHandler = key => {
this.setState(prevState => {
return {
selectedItem: prevState.images.find(image => {
return image.key === key;
})
};
});
console.log(selectedItem);
};
showModal = (key) => {
this.setState({
mvisible: true,
selectedItem: key
});
}
render () {
return (
<View style={{ flex: 1 }}>
<Modal
visible={this.state.mvisible}
onRequestClose={this.modalClosedHandler}>
<View style={{flex : 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Hello this is modal{this.state.selectedItem}</Text>
<Button title="Close" onPress={this.modalClosedHandler}/>
</View>
</Modal>
<ScrollView contentContainerStyle={{ paddingVertical: 20 }}>
{images.map(({ name, image, url, key }) => (
<Card title={`Product ${key}`} image={image} key={key}>
<Text style={{ marginBottom: 10 }}>
Photo by {name}.
</Text>
<Button
backgroundColor="#03A9F4"
title="VIEW NOW"
onPress={(key)=>this.showModal(key)}
/>
</Card>
))}
</ScrollView>
</View>
);
}
}
export default Home;
I am new to react native.
You wont get key in the first parameter of button's onPress.
This is wrong:
<Button
backgroundColor="#03A9F4"
title="VIEW NOW"
onPress={(key)=>this.showModal(key)}
/>
You already have a key at higher level, so you should use this code:
<Button
backgroundColor="#03A9F4"
title="VIEW NOW"
onPress={()=>this.showModal(key)}
/>
I'm not sure to understand well but if you have a problem while calling this.showModal is because you have an extra "key".
Replace
<Button
backgroundColor="#03A9F4"
title="VIEW NOW"
onPress={(key)=>this.showModal(key)}
/>
By
<Button
backgroundColor="#03A9F4"
title="VIEW NOW"
onPress={()=>this.showModal(key)}
/>

Resources