I want to pass the id from the current item to the function to delete it.
import React, { useState, useContext, useLayoutEffect } from "react";
import { View, Text, StyleSheet, TextInput, Image, ActivityIndicator } from "react-native";
import { FlatList, TouchableOpacity, Directions } from "react-native-gesture-handler";
import { AntDesign, Ionicons, Feather } from '#expo/vector-icons';
import firebase from "../firebase"
import { AuthContext } from "../AuthNavigator";
import Swipeout from "react-native-swipeout";
console.disableYellowBox = true;
export default function Ingredients() {
//In this Function i want to get the id from the Item to pass it into the function to delete the item
const swipeButtons = [
{
text: <AntDesign name="delete" size={24} color="black" />,
backgroundColor: '#AD1457',
onPress: () => handleRemoveItem(index)
}
]
const renderItem = ({ item }) => (
< Swipeout
autoClose
right={swipeButtons}
backgroundColor="transparent"
>
<View style={styles.item} >
<View style={{ flexDirection: "row", marginTop: 5 }} >
<Image style={styles.image} source={{ uri: item.image }}></Image>
<Text style={{ color: '#fff', marginTop: 5, marginLeft: 50, fontSize: 18 }}>Menge</Text>
<Text style={{ color: '#fff', marginTop: 35, marginLeft: -30, fontSize: 18 }}>{item.amount}</Text>
<Text style={{ color: '#fff', marginTop: 10, marginLeft: 80, fontSize: 22 }}>{item.label}</Text>
</View>
</View >
</Swipeout >
)
const [searchValue, setSearchValue] = useState('');
return (
<View style={styles.container}>
<View style={styles.searchBar}>
<View style={{ alignSelf: "flex-end", marginTop: 8, marginRight: 30 }}>
<TouchableOpacity onPress={() => fetchIngredient(searchValue)}>
{!isLoading && <Ionicons name="md-add" size={32} color="#fff" />}
</TouchableOpacity>
{isLoading && <ActivityIndicator style={styles.loading} color='#AD1457' />}
</View>
{!isLoading && <TextInput style={{
alignSelf: "flex-start", marginLeft: 25, marginTop: -30, fontSize: 20, color: '#fff', width: 200
}} placeholder="Suche" placeholderTextColor='#fff' value={searchValue} onChangeText={(searchValue) => setSearchValue(searchValue)}></TextInput>}
</View>
<FlatList
data={userIngredientsList}
renderItem={renderItem}
keyExtractor={(item) => item.id}>
</FlatList>
</View >
);
}
I need to pass it into the swipeButtons function, to pass it into the handleRemoveItem function and delete the item from the list. It would be nice if you give me some good ideas and not only short answers.
I'm new to react and don't know how to fix it.
Instead of directly using an array use it as a function and pass the Id or whatever the property you need.
const swipeButtons =(id)=> [
{
text: <AntDesign name="delete" size={24} color="black" />,
backgroundColor: '#AD1457',
onPress: () => handleRemoveItem(id)
}
]
const renderItem = ({ item }) => {
const buttons = swipeButtons(item.id);
return (
< Swipeout
autoClose
right={buttons}
backgroundColor="transparent"
>
<View style={styles.item} >
<View style={{ flexDirection: "row", marginTop: 5 }} >
<Image style={styles.image} source={{ uri: item.image }}></Image>
<Text style={{ color: '#fff', marginTop: 5, marginLeft: 50, fontSize: 18 }}>Menge</Text>
<Text style={{ color: '#fff', marginTop: 35, marginLeft: -30, fontSize: 18 }}>{item.amount}</Text>
<Text style={{ color: '#fff', marginTop: 10, marginLeft: 80, fontSize: 22 }}>{item.label}</Text>
</View>
</View >
</Swipeout >
);
}
< Swipeout
autoClose
right={swipeButtons(index)}
backgroundColor="transparent"
>
const swipeButtons = ({index}) =
{
text: <AntDesign name="delete" size={24} color="black" />,
backgroundColor: '#AD1457',
onPress: () => handleRemoveItem(index)
}
I'm not familliar with functional components but this way must works
Related
From App.js, I declare the "FollowingScreen", which is made of a module that exports "Following"
export const FollowingScreen = ({route, navigation}) => {
return (
<ScrollView style={styles.scrollView}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: "#262423" }}>
<Following />
</View>
</ScrollView>
);
}
"Following" is exported by a file called "following.js". From "following.js" I want to navigate to ProfileScreen:
import { useNavigation } from '#react-navigation/native';
class Following extends Component {
...
...
renderItem = ({item}, navigation) => (
<ListItem bottomDivider>
<ListItem.Content style={{width: '100%', display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<ListItem.Title>{item.title}</ListItem.Title>
<TouchableOpacity
onPress={() => navigation.navigate("ProfileScreen", {userInfo: {uri: item.probability, username: item.country_id, id_user: item.id_user}})}
style={{ flexDirection: 'row'}}
>
<Image
style={{ borderRadius: 50 }}
source={{ uri: item.probability, width: 48, height: 48 }}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate("ProfileScreen", {userInfo: {uri: item.probability, username: item.country_id, id_user: item.id_user}})}
style={{ flexDirection: 'row'}}
>
<ListItem.Subtitle style={{color: '#000'}}>
<Text style={{fontFamily: 'Montserrat_600SemiBold' }}>{item.name} {item.surname}</Text>
{"\n"}
<Text style={{fontFamily: 'Montserrat_600SemiBold' }}>#{item.country_id}</Text>
{"\n"}
{"\n"}
<Text style={{fontFamily: 'Montserrat_600SemiBold' }}>{item.followers}</Text>
{"\n"}
<Text style={{fontFamily: 'Montserrat_600SemiBold' }}>{item.total}</Text> Total
</ListItem.Subtitle>
</TouchableOpacity>
<Button
buttonStyle={{backgroundColor: "#a6aba7", padding: 9, textAlign: "right", borderRadius: 10, display: item.isFollowing=="Same user" ? "none" : "flex"}}
title={item.isFollowing}
onPress={() => {
if(item.isFollowing=="Follow"){
this.follow(item.id_user);
}
else if(item.isFollowing=="Unfollow"){
this.unfollow(item.id_user);
}
else if(item.isFollowing=="Same user"){
//alert("Same user");
}
}}
/>
</ListItem.Content>
</ListItem>
);
}
unfortunately, I get "undefined is not an object (evaluating 'navigation.navigate')"
You are not passing navigation as a prop to the Following component so change your FollowingScreen component likewise :
export const FollowingScreen = ({route, navigation}) => {
{/** Rest Of Code **/}
<Following navigation={navigation}/>
{/** Rest of Code **/}
}
Then in Following class use this.props.navigation.navigate(....).
You need to declare "navigation" before calling it:
const navigation = useNavigation();
right before
renderItem = (...)
I'm making a to-do list app. I need to store the input value locally or somewhere so that I can show them in the app even if the app is opened after closing once. Now when I'm closing the app and restarting all the previous values is being vanished. But I want to keep the previous data and If new data is given that will also be stored if I don't delete that manually. How can I solve this problem? I'm using expo.
Here is my code:
import React, { useState } from 'react';
import { View, Text, StyleSheet, Button, FlatList, TouchableOpacity, TextInput, ScrollView } from 'react-native';
import { MaterialIcons } from '#expo/vector-icons'
import Line from './Line';
function App() {
//storing data in array
const [initialElements, changeEl] = useState([
]);
const [value, setValue] = useState('')
const [idx, incr] = useState(1);
const [exampleState, setExampleState] = useState(initialElements);
//add button
const addElement = () => {
if (value != '') {
var newArray = [...initialElements, { id: idx, title: value }];
incr(idx + 1);
setExampleState(newArray);
changeEl(newArray);
}
}
//delete button
const delElement = (id) => {
let newArray = initialElements.filter(function (item) {
return item.id !== id
})
setExampleState(newArray);
changeEl(newArray);
}
//showing item
const Item = ({ title, id }) => (
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}>
<View style={{ borderWidth: 2, margin: 5, flex: 1, padding: 10, borderRadius: 10 }}>
<TouchableOpacity onPress={() => { alert(title) }}>
<Text >{title}</Text>
</TouchableOpacity>
</View>
<TouchableOpacity onPress={() => delElement(id)}>
<MaterialIcons name='delete' size={24} />
</TouchableOpacity>
</View>
);
//calling item for render
const renderItem = ({ item }) => {
<Item title={item.title} id={item.id} />
}
return (
<View style={styles.container}>
<View style={{ alignItems: 'center', marginBottom: 10 }}>
<Text style={{ fontSize: 20, fontWeight: '500' }}> To <Text style={{ color: 'skyblue', fontWeight: '900' }}>Do</Text> List</Text>
<Line />
</View>
<View>
<TextInput onChangeText={text => setValue(text)} placeholder="Enter to Todo" style={{ borderWidth: 2, borderRadius: 10, backgroundColor: 'skyblue', height: 40, paddingLeft: 10, borderColor: 'black' }}></TextInput>
</View>
<View style={{ alignItems: 'center' }}>
<TouchableOpacity onPress={() => addElement()} style={{ marginTop: 10 }}>
<View style={{ backgroundColor: 'black', width: 70, height: 40, justifyContent: 'center', borderRadius: 10 }}>
<Text style={{ color: 'white', textAlign: 'center' }}>Add</Text>
</View>
</TouchableOpacity>
</View>
<FlatList
style={{ borderWidth: 2, padding: 10, flex: 1, backgroundColor: '#EEDDD0', marginTop: 10 }}
data={exampleState}
renderItem={renderItem}
keyExtractor={item => item.id.toString()
}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
margin: 5,
}
})
export default App;
React Native provides a local storage option called AsyncStorage. You might use asyncstorage to save the data locally on the device and get that data inside useEffect() hook on startup.
You can find more about AsyncStorage here.
Although this is deprecated and now community package " #react-native-async-storage/async-storage " is used. The implementation remains the same.
I am trying to implement a function in Expo to filter my data using checkboxes. I have already completed my checkboxes and designed them accordingly. The data to be filtered is pulled from the Firebase database and displayed in the form of a list on my page. I have also created a button for the filtering, which is used so that when a user clicks this button, the filtering takes place according to the selection of the respective boxes. Attached is a picture that shows what has already been implemented and below the code for it. I would be very grateful if someone could help me with this, as I am relatively new to React Native and have not found anything in this regard.
Thanks in advance
Anbieterliste-Screen
function MyCheckbox() {
const [checked, onChange] = useState(false);
function onCheckmarkPress() {
onChange(!checked);
}
return (
<Pressable
style={[styles.checkboxBase, checked && styles.checkboxChecked]}
onPress={onCheckmarkPress}>
{checked && <Ionicons name="checkmark" size={18} color="white" />}
</Pressable>
);
}
export default function Anbieter({ route, navigation }) {
//CONSTS WHICH WE GOT FROM THE HOMEPAGE AND DECLARATION
const { latitude, longitude, address } = route.params;
var getLat = latitude;
var getLong = longitude;
var getAddress = JSON.stringify(address);
const [restaurentList, setRestaurentList] = useState()
const [currentUsers, setCurrentUsers] = useState()
const [ranges, setRanges] = useState(1)
const [showRange, setShowRange] = useState(false)
// THIS IS A LIST WHICH DISPLAY ALL RESTAURANTS BY GETTING DATA IN PARAMS IN NAME OF DATA
const ListButton = ({ title, data }) => {
return (
<TouchableOpacity onPress={() => { navigation.navigate('Produktubersicht', { data }) }} style={[styles.itemContainer]}>
<Image source={{ uri: data.anbieterImg }} style={{ width: '90%', marginLeft: '5%', height: 160 }} />
<Text style={{ fontSize: 16, fontWeight: "bold", marginLeft: 20 }}>{data.firmenname}</Text>
<Text style={{ fontSize: 16, fontWeight: "bold", marginLeft: 20, width: '90%' }}>Adresse:
<Text style={{ fontSize: 16, fontWeight: 'normal' }}>{data.adresse}</Text>
</Text>
<Text style={{ fontSize: 16, fontWeight: "bold", marginLeft: 20, width: '90%' }}>Kategorie:
<Text style={{ fontSize: 16, fontWeight: 'normal' }}>{data.kategorie}</Text>
</Text>
</TouchableOpacity>
);
}
// THIS FUNCTION IS USE TO CALL ALL RESTAURANT FROM FIREBASE DATABASE
const getRestaurents = async () => {
let arr = []
// THIS IS FIREBASE API ALL DATA IS COMING FROM FIREBASE
var ar = await firebase.database().ref("/anbieter/").once("child_added", snapshot => {
var obj = snapshot.val();
obj.id = snapshot.key;
arr.push(obj);
});
// ALL DATA OF RESTAURANT IS STORING IN STATE HERE THEN FROM HERE ALL DATA WILL DISPLAY
setRestaurentList(arr)
}
var users = firebase.auth().currentUser;
useEffect(() => {
// WE CALL GET RESTAURANTS API HERE BECAUSE THIS USEEFFECT JUST CALL ONCE WHEN COMPONENT RENDER
console.log(users, 'users');
getRestaurents()
}, []);
// THIS IS SIGN OUT BUTTON , WHEN USER CLICK FOR SIGNOUT THEN IT ASKS WHETHER HE/SHE IS SURE TO DO SO
const signOutFunc = async () => {
Alert.alert(
"Ausloggen?",
"Sind Sie sicher, dass Sie sich ausloggen möchten?",
[
{
text: "Bestätigen", onPress: async () => {
await AsyncStorage.removeItem('userName')
await AsyncStorage.removeItem('order')
firebase.auth().signOut();
navigation.navigate('Homepage');
}
},
{
text: "Abbrechen",
style: "cancel"
}
]
);
}
return (
<ScrollView>
{/* THIS IS THE PART OF ICON WHERE LOGIN , SIGNOUT , Bestellverlauf AND Warenkorb ICON ARE HERE */}
<View style={styles.container}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginRight: 5, marginVertical: 10 }}>
{users ?
<TouchableOpacity onPress={() => { signOutFunc() }}>
<Entypo name="log-out" size={30} color="black" />
</TouchableOpacity>
: null}
{users ?
<View style={{ flexDirection: 'row', }}>
<TouchableOpacity onPress={() => { navigation.navigate('Bestellverlauf') }} style={{ marginRight: 20 }}>
<Fontisto name="prescription" size={30} color="black" />
</TouchableOpacity>
<TouchableOpacity onPress={() => { navigation.navigate('Warenkorb') }}>
<Feather name="shopping-bag" size={30} color="black" />
</TouchableOpacity>
</View>
:
<TouchableOpacity style={{ flexDirection: 'row' }} onPress={() => { navigation.navigate('Anmelden') }}>
<FontAwesome5 name="user" size={30} color="black" />
<Text style={{ margin: 10 }}>Registration/Login</Text>
</TouchableOpacity>
}
</View>
<Text style={styles.textFirst}>Ermittelte Adresse:</Text>
<View style={{ alignContent: 'center', flexDirection: 'row', width: '90%' }}>
<Text style={{ marginBottom: 15, marginTop: 10, marginHorizontal: 10 }}>{getAddress} </Text>
<TouchableOpacity onPress={() => { setShowRange(!showRange) }}>
<MaterialCommunityIcons name="filter-plus" size={30} color="grey" />
</TouchableOpacity>
</View>
{/* THIS IS RANGE SLIDER FOR SORTING ALL RESTAURANTS */}
{showRange ?
<View>
<View style={{ flexDirection: 'row', justifyContent: "space-between" }}>
<Text style={{ marginLeft: '3%', fontSize: 14, fontWeight: 'bold' }}> Entfernung festlegen!</Text>
<Text style={{ marginLeft: '3%' }}> {Math.round(ranges)} km</Text>
</View>
<Slider maximumValue={100} style={{ width: '90%', marginLeft: '5%', marginTop: 10, }} value={ranges} onValueChange={(e) => setRanges(e)} />
<View style={{ marginTop: 10 }}>
<Text style={{ marginLeft: '3%', fontSize: 14, fontWeight: 'bold', marginBottom: 10, }}>Filterung nach Kategorie</Text>
<View style={styles.checkboxContainer}>
<MyCheckbox />
<Text style={styles.checkboxLabel}>Backware</Text>
</View>
<View style={styles.checkboxContainer}>
<MyCheckbox />
<Text style={styles.checkboxLabel}>Bioprodukte</Text>
</View>
<View style={styles.checkboxContainer}>
<MyCheckbox />
<Text style={styles.checkboxLabel}>Feinkost</Text>
</View>
<View style={styles.checkboxContainer}>
<MyCheckbox />
<Text style={styles.checkboxLabel}>Griechische Spezialitäten</Text>
</View>
<View style={styles.checkboxContainer}>
<MyCheckbox />
<Text style={styles.checkboxLabel}>Molkerei</Text>
</View>
<View style={styles.checkboxContainer}>
<MyCheckbox />
<Text style={styles.checkboxLabel}>Türkische Spezialitäten</Text>
</View>
<Button title="Filter anwenden..." color='#5271FF'/>
</View>
</View>
: null
}
<Text style={styles.textSecond}>Sie können gerne die Filterfunktion verwenden, indem Sie oben auf den Symbol klicken...</Text>
{restaurentList && restaurentList.map((val, i) => {
return <ListButton key={i} title={val.firmenname} data={val} />
})}
</View>
</ScrollView>
);
}
A better approach to avoid duplication of code is to create a filterList array and create dynamic filters component.
I modified your code, check the comments for the explanation.
function MyCheckbox({addFilter, removeFilter, filterIndex}) { // ADD THIS PROPS TO ADD AND REMOVE FILTERS
const [checked, onChange] = useState(false);
function onCheckmarkPress() {
onChange(!checked);
checked ? addFilter(filterIndex) : removeFilter(filterIndex)
}
return (
<Pressable
style={[styles.checkboxBase, checked && styles.checkboxChecked]}
onPress={onCheckmarkPress}>
{checked && <Ionicons name="checkmark" size={18} color="white" />}
</Pressable>
);
}
export default function Anbieter({ route, navigation }) {
//CONSTS WHICH WE GOT FROM THE HOMEPAGE AND DECLARATION
const { latitude, longitude, address } = route.params;
var getLat = latitude;
var getLong = longitude;
var getAddress = JSON.stringify(address);
const [restaurentList, setRestaurentList] = useState()
const [filteredRestaurantList, setFilteredRestaurentList] = useState() // <-- ADD THIS STATE TO KEEP TRACK OF THE FILTERED LIST TO DISPLAY
const [currentUsers, setCurrentUsers] = useState()
const [ranges, setRanges] = useState(1)
const [showRange, setShowRange] = useState(false)
const [filters, setFilters] = useState([]) // <-- ADD THIS STATE TO KEEP TRACK OF THE FILTERS SELECTED
const filterList = ["Backware", "Bioprodukte", "Feinkost", "Griechische Spezialitäten"] // <--- CREATE A FILTER ARRAY
const addFilter = (filterIndex) => { // <-- FUNCTION ADD FILTER
setFilters([...filters, filterList[filterIndex]])
}
const removeFilter = (filterIndex) => { // <-- FUNCTION REMOVE FILTER
const index = filters.indexOf(filterList[filterIndex]);
const newFilters = [...filters];
newFilters.splice(index, 1)
setFilters(newFilters)
}
// THIS IS A LIST WHICH DISPLAY ALL RESTAURANTS BY GETTING DATA IN PARAMS IN NAME OF DATA
const ListButton = ({ title, data }) => {
return (
<TouchableOpacity onPress={() => { navigation.navigate('Produktubersicht', { data }) }} style={[styles.itemContainer]}>
<Image source={{ uri: data.anbieterImg }} style={{ width: '90%', marginLeft: '5%', height: 160 }} />
<Text style={{ fontSize: 16, fontWeight: "bold", marginLeft: 20 }}>{data.firmenname}</Text>
<Text style={{ fontSize: 16, fontWeight: "bold", marginLeft: 20, width: '90%' }}>Adresse:
<Text style={{ fontSize: 16, fontWeight: 'normal' }}>{data.adresse}</Text>
</Text>
<Text style={{ fontSize: 16, fontWeight: "bold", marginLeft: 20, width: '90%' }}>Kategorie:
<Text style={{ fontSize: 16, fontWeight: 'normal' }}>{data.kategorie}</Text>
</Text>
</TouchableOpacity>
);
}
// THIS FUNCTION IS USE TO CALL ALL RESTAURANT FROM FIREBASE DATABASE
const getRestaurents = async () => {
let arr = []
// THIS IS FIREBASE API ALL DATA IS COMING FROM FIREBASE
var ar = await firebase.database().ref("/anbieter/").once("child_added", snapshot => {
var obj = snapshot.val();
obj.id = snapshot.key;
arr.push(obj);
});
// ALL DATA OF RESTAURANT IS STORING IN STATE HERE THEN FROM HERE ALL DATA WILL DISPLAY
setRestaurentList(arr)
setFilteredRestaurentList(arr)
}
var users = firebase.auth().currentUser;
useEffect(() => {
// WE CALL GET RESTAURANTS API HERE BECAUSE THIS USEEFFECT JUST CALL ONCE WHEN COMPONENT RENDER
console.log(users, 'users');
getRestaurents()
}, []);
useEffect(() => { // <--- ADD THIS TO UPDATE THE FILTER RESTAURANT LIST EVERY TIME THAT THE FILTER ARRAY CHANGE
const rList = [...restaurentList];
if (filters.length) {
const filteredList = rList.filter(r => {
const toAdd = filters.indexOf(r.category)
if (toAdd !== -1) {
return r
}
})
setFilteredRestaurentList(filteredList)
}else { // <-- IF THERE ARE NO FILTER; RESET TO ORIGINAL LIST
setFilteredRestaurentList(rList)
}
}, [filters]);
return (
<ScrollView>
{/* THIS IS THE PART OF ICON WHERE LOGIN , SIGNOUT , Bestellverlauf AND Warenkorb ICON ARE HERE */}
<View style={styles.container}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginRight: 5, marginVertical: 10 }}>
{users ?
<TouchableOpacity onPress={() => { signOutFunc() }}>
<Entypo name="log-out" size={30} color="black" />
</TouchableOpacity>
: null}
{users ?
<View style={{ flexDirection: 'row', }}>
<TouchableOpacity onPress={() => { navigation.navigate('Bestellverlauf') }} style={{ marginRight: 20 }}>
<Fontisto name="prescription" size={30} color="black" />
</TouchableOpacity>
<TouchableOpacity onPress={() => { navigation.navigate('Warenkorb') }}>
<Feather name="shopping-bag" size={30} color="black" />
</TouchableOpacity>
</View>
:
<TouchableOpacity style={{ flexDirection: 'row' }} onPress={() => { navigation.navigate('Anmelden') }}>
<FontAwesome5 name="user" size={30} color="black" />
<Text style={{ margin: 10 }}>Registration/Login</Text>
</TouchableOpacity>
}
</View>
<Text style={styles.textFirst}>Ermittelte Adresse:</Text>
<View style={{ alignContent: 'center', flexDirection: 'row', width: '90%' }}>
<Text style={{ marginBottom: 15, marginTop: 10, marginHorizontal: 10 }}>{getAddress} </Text>
<TouchableOpacity onPress={() => { setShowRange(!showRange) }}>
<MaterialCommunityIcons name="filter-plus" size={30} color="grey" />
</TouchableOpacity>
</View>
{/* THIS IS RANGE SLIDER FOR SORTING ALL RESTAURANTS */}
{showRange ?
<View>
<View style={{ flexDirection: 'row', justifyContent: "space-between" }}>
<Text style={{ marginLeft: '3%', fontSize: 14, fontWeight: 'bold' }}> Entfernung festlegen!</Text>
<Text style={{ marginLeft: '3%' }}> {Math.round(ranges)} km</Text>
</View>
<Slider maximumValue={100} style={{ width: '90%', marginLeft: '5%', marginTop: 10, }} value={ranges} onValueChange={(e) => setRanges(e)} />
<View style={{ marginTop: 10 }}>
<Text style={{ marginLeft: '3%', fontSize: 14, fontWeight: 'bold', marginBottom: 10, }}>Filterung nach Kategorie</Text>
{filterList.map((filterItem, index) => (
<View
key={index}
style={styles.checkboxContainer}>
<MyCheckbox
addFilter={addFilter} // <-- ADD THIS PROP
removeFilter={removeFilter} // <-- ADD THIS PROP
filterIndex={index} // <-- ADD THIS PROP
/>
<Text style={styles.checkboxLabel}>filterItem</Text>
</View>
))}
<Button title="Filter anwenden..." color='#5271FF'/>
</View>
</View>
: null
}
<Text style={styles.textSecond}>Sie können gerne die Filterfunktion verwenden, indem Sie oben auf den Symbol klicken...</Text>
{filteredRestaurantList && filteredRestaurantList.map((val, i) => {
return <ListButton key={i} title={val.firmenname} data={val} />
})}
</View>
</ScrollView>
);
}
I need to pass Flatlist data to modal in react native. Like, on click the item from the flatlist, it shows the modal with data for selected item. Here is my code below
Home.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, FlatList, Image, TouchableOpacity, Alert, Button } from 'react-native';
import { Popup } from './Modal';
import * as productdata from '../data/productdata.js';
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
};
}
componentDidMount() {
this.setState({
isLoading: false,
dataSource: productdata.product,
})
}
popupRef = React.createRef()
onShowPopup = item => {
popupRef.show();
}
onClosePopup = () => {
popupRef.close()
}
ProductList = ({ item }) => (
<View style={styles.listItem}>
<TouchableOpacity onPress={() => this.onShowPopup(item)} style={{ height: 100, width: 100, justifyContent: "center", alignItems: "center" }}>
<Image source={item.photo} style={{ width: 100, height: 100, borderRadius: 15 }} />
</TouchableOpacity>
<View style={{ alignItems: "center", flex: 1, marginTop: 20 }}>
<Text style={{ fontWeight: "bold", fontSize: 22 }}>{item.name}</Text>
<Text style={{ fontSize: 18, fontWeight: "bold" }}>{item.price}</Text>
</View>
<Popup name="Product Details" ref={(target) => popupRef = target} onTouchOutside={this.onClosePopup} />
</View>
);
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
renderItem={this.ProductList}
keyExtractor={item => item.name}
/>
</View>
);
}
}
Modal.js
import React, { Component } from 'react';
import { Modal, Dimensions, TouchableWithoutFeedback, StyleSheet, View, Text, Button, Image, TouchableOpacity } from 'react-native';
const deviceHeight = Dimensions.get("window").height
export class Popup extends Component {
constructor(props) {
super(props)
this.state = {
show: false,
}
}
show = () => {
this.setState({ show: true })
}
close = () => {
this.setState({ show: false })
}
renderOutsideTouchable(onTouch) {
const view = <View style={{ flex: 1, width: '100%' }} />
if (!onTouch) return view
return (
<TouchableWithoutFeedback onPress={onTouch} style={{ flex: 1, width: '100%' }}>
{view}
</TouchableWithoutFeedback>
)
}
renderTitle = () => {
const { name } = this.props
return (
<View style={{ alignItems: 'center' }}>
<Text style={{
color: 'black', fontSize: 20,
fontWeight: 'bold', margin: 15
}}>
{name}
</Text>
</View>
)
}
renderContent = (item) => {
return (
<View style={{ alignItems: 'center', marginBottom: 10 }}>
<View style={styles.card}>
<Text style={{ fontSize: 20, fontWeight: '500', fontWeight: 'bold', alignSelf: 'center', margin: 5 }}/>
<TouchableOpacity style={styles.buttonContainer}>
<Text style={styles.button}>Add to Cart</Text>
</TouchableOpacity>
</View>
</View>
)
}
render() {
let { show } = this.state
const { onTouchOutside, title } = this.props
return (
<Modal animationType={'slide'} transparent={true} visible={show} onRequestClose={this.close}>
<View style={{ flex: 1, backgroundColor: '#000000AA', justifyContent: 'flex-end' }}>
{this.renderOutsideTouchable(onTouchOutside)}
<View style={{
backgroundColor: '#FFFFFF', width: '100%', height: '70%', borderTopRightRadius:20, borderTopLeftRadius: 20, paddingHorizontal: 20, maxHeight: deviceHeight * 5}}>
{this.renderTitle()}
{this.renderContent()}
</View>
</View>
</Modal>
)
}
}
My Problem: I am not able to pass the flatlist item data to a Modal component and have no better idea solving it in this code.
Please help me and if any including, changes or complete solution for perfect understanding for the requirement would be really great. Many Thanks in Advance!
You don't need to duplicate open state in modal/popup. Simply set the style and open. Assume open close state is controlled by parent component, so if rendering modal/popup it is open by definition.
class Popup extends React.Component {
renderOutsideTouchable(onTouch) {
const view = <View style={{ flex: 1, width: '100%' }} />;
if (!onTouch) return view;
return (
<TouchableWithoutFeedback
onPress={onTouch}
style={{ flex: 1, width: '100%' }}>
{view}
</TouchableWithoutFeedback>
);
}
renderTitle = () => {
const { name } = this.props;
return (
<View style={{ alignItems: 'center' }}>
<Text
style={{
color: 'black',
fontSize: 20,
fontWeight: 'bold',
margin: 15,
}}>
{name}
</Text>
</View>
);
};
renderContent = () => {
const { item } = this.props;
return (
<View style={{ alignItems: 'center', marginBottom: 10 }}>
<View style={styles.card}>
<Text
style={{
fontSize: 20,
fontWeight: '500',
// fontWeight: "bold",
alignSelf: 'center',
margin: 5,
}}
/>
<TouchableOpacity style={styles.buttonContainer}>
<Text>Name: {item.name}</Text>
<Text>Price: {item.price}</Text>
<Text>Description: {item.desc}</Text>
<Text>Rating: {item.rating}</Text>
<Text style={styles.button}>Add to Cart</Text>
</TouchableOpacity>
</View>
</View>
);
};
render() {
const { onTouchOutside, title } = this.props;
return (
<Modal
animationType={'slide'}
transparent
visible // <-- visible prop is truthy
onRequestClose={this.close}>
<View
style={{
flex: 1,
backgroundColor: '#000000AA',
justifyContent: 'flex-end',
zIndex: 1000,
}}>
{this.renderOutsideTouchable(onTouchOutside)}
<View
style={{
backgroundColor: '#FFFFFF',
width: '100%',
height: '70%',
borderTopRightRadius: 20,
borderTopLeftRadius: 20,
paddingHorizontal: 20,
maxHeight: deviceHeight * 5,
}}>
{this.renderTitle()}
{this.renderContent()}
</View>
</View>
</Modal>
);
}
}
A react ref isn't necessary for opening a modal/popup to display a specific item. Change the onShowPopup and onClosePopup to set/nullify a clicked on item. Conditionally render the Popup outside the Flatlist.
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
dataSource: productdata.product,
isLoading: false,
popupItem: null,
};
}
onShowPopup = (popupItem) => {
this.setState({ popupItem });
};
onClosePopup = () => {
this.setState({ popupItem: null });
};
ProductList = ({ item }) => (
<View style={styles.listItem}>
<TouchableOpacity
onPress={() => this.onShowPopup(item)}
style={{
height: 100,
width: 100,
justifyContent: 'center',
alignItems: 'center',
}}>
<Image
source={item.photo}
style={{ width: 100, height: 100, borderRadius: 15 }}
/>
</TouchableOpacity>
<View style={{ alignItems: 'center', flex: 1, marginTop: 20 }}>
<Text style={{ fontWeight: 'bold', fontSize: 22 }}>{item.name}</Text>
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>{item.price}</Text>
</View>
</View>
);
render() {
return (
<View style={styles.container}>
{this.state.popupItem && (
<Popup
name="Product Details"
item={this.state.popupItem} // <-- pass pop item
onTouchOutside={this.onClosePopup}
/>
)}
<FlatList
data={this.state.dataSource}
renderItem={this.ProductList}
keyExtractor={(item) => item.name}
/>
</View>
);
}
}
Expo Snack
there is way to pass a function into "onpress" ?
i need to pass the "postData" function into the "onpress" button ,
how can i do it?
in my code the has 2 "onpress" that i want to pass inside the "postData" .
if there some mistake so please let me know and i will fix it .
this is my code for example :
export default class OrderInformationScreen extends Component {
constructor(props) {
super(props);
const { state } = props.navigation;
this.state = {
title: state.params.data
}
//alert(JSON.stringify((state.params.data.SHORT_TEXT)))
}
postData = () => {
const postData = {
ACTOR_ID:"APAZ",
REPORT_KEY:"001",
WORK_ITEM_ID:"000018639250",
NOTE:"fun all time"
}
const axios = require('axios')
axios.post('https://harigotphat1.mekorot.co.il/ConfirmPackaotWS/OrderApprove/OrderApprove_OrderApp_Save_Approvement/'+ postData)
.then(function (response) {
console.log("roei response======>>>>",response);
})
}
render() {
return (
<>
<View
style={{
alignItems: 'flex-start',
justifyContent: 'center',
borderColor: 'blue',
flexDirection: "row",
justifyContent: 'space-evenly'
}}>
<TouchableOpacity onPress={() => console.log("cancel!")}>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
onPress={() => console.log("cancel!")} />
<View >
<Text style={{ fontSize: 25, fontWeight: 'bold', color: 'red' }}>לדחות</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => console.log("works!")}> ///HERE I NEED PASS postData
<Avatar
size='large'
activeOpacity={0.1}
rounded
source={require('../assets/up.png')} style={{ height: 80, width: 80 }}
onPress={() => console.log("Works!")} />
<View>
<Text style={{ fontSize: 25, fontWeight: 'bold', color: 'green', marginHorizontal: 6 }}>לאשר</Text>
</View>
</TouchableOpacity>
</View>
<InfoTable headerInfo={this.state.title}></InfoTable>
</>
);
};
}
Check this updated code
export default class OrderInformationScreen extends Component {
constructor(props) {
super(props);
const { state } = props.navigation;
this.state = {
title: state.params.data
};
//alert(JSON.stringify((state.params.data.SHORT_TEXT)))
}
postData = () => {
const postData = {
ACTOR_ID: "APAZ",
REPORT_KEY: "001",
WORK_ITEM_ID: "000018639250",
NOTE: "fun all time"
};
const axios = require("axios");
axios
.post(
"https://harigotphat1.mekorot.co.il/ConfirmPackaotWS/OrderApprove/OrderApprove_OrderApp_Save_Approvement/" +
postData
)
.then(function(response) {
console.log("roei response======>>>>", response);
});
};
render() {
return (
<>
<View
style={{
alignItems: "flex-start",
justifyContent: "center",
borderColor: "blue",
flexDirection: "row",
justifyContent: "space-evenly"
}}
>
<TouchableOpacity onPress={() => console.log("cancel!")}>
<Avatar
size="large"
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require("../assets/down.png")}
style={{ height: 80, width: 80 }}
onPress={() => console.log("cancel!")}
/>
<View>
<Text style={{ fontSize: 25, fontWeight: "bold", color: "red" }}>
לדחות
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.postData()}>
<Avatar
size="large"
activeOpacity={0.1}
rounded
source={require("../assets/up.png")}
style={{ height: 80, width: 80 }}
onPress={() => console.log("Works!")}
/>
<View>
<Text
style={{
fontSize: 25,
fontWeight: "bold",
color: "green",
marginHorizontal: 6
}}
>
לאשר
</Text>
</View>
</TouchableOpacity>
</View>
<InfoTable headerInfo={this.state.title}></InfoTable>
</>
);
}
}
Simply you can put function like this way
<TouchableOpacity onPress={() => this.postData()}> .... </TouchableOpacity>