select one item from flatlist - react-native

I created this list of items and I want to let user select one item and then change style of this item.
this is my approach:
class Gift extends React.Component {
constructor(props){
super(props)
this.titleUpValue = new Animated.Value(0);
this.state = {
isLoading: false,
listGifts: [
{
"id" : "1",
"type" : 'gift' ,
"etat" : 1,
"titreTransaction": "عدد الوحدات",
"contenuTrans": "400",
"dateTrans": "2019-07-31 17:47:31"
},
{
"id" : "2",
"type" : 'ba' ,
"etat" : 1,
"titreTransaction": "عدد الوحدات",
"contenuTrans": "1000",
"dateTrans": "2019-07-31 17:42:57"
},
{
"id" : "3",
"type" : 'ba' ,
"etat" : 1,
"titreTransaction": "عدد الوحدات",
"contenuTrans": "500",
"dateTrans": "2019-07-31 17:31:35"
},
}
],
itemId: null,
btnDisabled: true,
itemindex: null,
}
}
PressedItem = (itemId) => {
this.setState({ itemId: itemId, btnDisabled: false,})
}
renderItem = ({ item }) => {
return (
<TouchableOpacity
onPress={() => { this.setState({ itemindex: item.id, itemId: item.id, btnDisabled: !this.state.btnDisabled, }), console.warn('id > ' + this.state.btnDisabled) }}
style= {[
StylesGift.giftItem,
this.state.itemindex === item.id ? StylesGift.SelectedlistItem : StylesGift.UnselectedlistItem
]}>
<Image source={Images.gift1}
style={StylesGift.imageStyle}
resizeMode={'contain'}
/>
<View style= {StylesGift.footGift}>
<View style= {StylesGift.nameGiftContainer}>
<View style= {StylesGift.valueGiftContainer}>
<Text style= {StylesGift.valueGiftText}>200</Text>
</View>
<Text style= {StylesGift.nameGiftText}>الهدايا</Text>
<Text style= {StylesGift.nameGiftText}>{item.id}</Text>
</View>
</View>
<View style= {StylesGift.headGift}>
<View style= {StylesGift.icGiftContainer}>
<IconFA name="check" size={hp('1.6%')} color= {Colors.white} style={StylesGift.icGift}/>
</View>
</View>
</TouchableOpacity>
)
}
render() {
return (
<View style={Styles.listContainer}>
{
this.state.isLoading ?
<ActivityIndicator size='large' style={Styles.styleAI} color={Colors.mainYellow}/>
:
<FlatList
style={Styles.flatlist}
contentContainerStyle={Styles.flatContent}
data={this.state.listGifts}
keyExtractor={(item) => item.id.toString()}
renderItem={this.renderItem}
numColumns={2}
/>
}
</View>
);
}
}
export default Gift;
I dont use the PressedItem function for test, the consol.warn() in onPress show the last state not the current state.
for exemple when I click on the item with id = "1" it show me id > null when I click on the item with id = "2" then it show me id > 1... and the style deosn't change even with this condition:
this.state.itemindex === item.id ? StylesGift.SelectedlistItem : StylesGift.UnselectedlistItem
this is the 3 main Styles:
giftItem: {
width: wp('42%'),
height: hp('30%'),
alignItems: 'center',
backgroundColor: Colors.white,
borderRadius: wp('2%'),
overflow: 'hidden',
marginVertical: wp('2%'),
marginHorizontal: wp('2%'),
// borderWidth: 1, borderColor: 'blue',
},
UnselectedlistItem: {
elevation: 2,
borderWidth: 1, borderColor: 'red',
},
SelectedlistItem: {
elevation: 8,
borderWidth: 1, borderColor: 'blue',
},
I think my approach is logic and most work but I don't know what's wrong, states: itemindex and itemId doesn't change in setState

It's okey, I just had to add extraData={this.state} as parameter in flatlist for telling the flatlist to re-render
<FlatList
style={Styles.flatlist}
contentContainerStyle={Styles.flatContent}
data={this.state.listGifts}
keyExtractor={(item) => item.id.toString()}
renderItem={this.renderItem}
numColumns={2}
extraData={this.state}
/>

Related

Add to cart in react native

I am creating my first professional react native app for a new start up, I like to do so.
This is based om a Product delarship.
Since I am not able to Pass the checked products to the Cart Page. Please Help me to do future.
I just created it in expo for react-native
Please Help me
Please Help I am stuck here.
import React from "react";
import styled from "styled-components";
import { Dimensions } from "react-native";
import { StatusBar } from "expo-status-bar";
import MedCard from "../components/MidCard";
import ProductName from "../components/Prices";
import Price from "../components/Prices";
import { LinearGradient } from "expo-linear-gradient";
import {
StyleSheet,
Button,
Text,
View,
TouchableOpacity,
ScrollView,
Image,
ActivityIndicator,
TextInput,
Alert,
} from "react-native";
import {
MaterialIcons,
AntDesign,
Ionicons,
MaterialCommunityIcons,
} from "#expo/vector-icons";
import { color } from "react-native-reanimated";
class Pulsars extends React.Component {
constructor(props) {
super(props);
this.state = {
selectAll: false,
cartItemsIsLoading: false,
cartItems: [
/* Sample data from walmart */
{
itemId: "1",
name: "Orid Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81f17QBywiL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "2",
name: "Orid Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81f17QBywiL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "3",
name: "Toor Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81ieFDa5gHL._SY550_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "4",
name: "Toor Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81ieFDa5gHL._SY550_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "5",
name: "Gram Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/udhayam-gram-dal-228x228-1.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "6",
name: "Gram Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/udhayam-gram-dal-228x228-1.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "7",
name: "Moong Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/12/819D8piBVKL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "8",
name: "Moong Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/12/819D8piBVKL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
],
};
}
selectHandler = (index, value) => {
const newItems = [...this.state.cartItems]; // clone the array
newItems[index]["checked"] = value == 1 ? 0 : 1; // set the new value
this.setState({ cartItems: newItems }); // set new state
};
selectHandlerAll = (value) => {
const newItems = [...this.state.cartItems]; // clone the array
newItems.map((item, index) => {
newItems[index]["checked"] = value == true ? 0 : 1; // set the new value
});
this.setState({
cartItems: newItems,
selectAll: value == true ? false : true,
}); // set new state
};
deleteHandler = (index) => {
Alert.alert(
"Are you sure you want to delete this item from your cart?",
"",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel",
},
{
text: "Delete",
onPress: () => {
let updatedCart = this.state.cartItems; /* Clone it first */
updatedCart.splice(
index,
1
); /* Remove item from the cloned cart state */
this.setState(updatedCart); /* Update the state */
},
},
],
{ cancelable: false }
);
};
quantityHandler = (action, index) => {
const newItems = [...this.state.cartItems]; // clone the array
let currentQty = newItems[index]["qty"];
if (action == "more") {
newItems[index]["qty"] = currentQty + 5;
} else if (action == "less") {
newItems[index]["qty"] = currentQty > 5 ? currentQty - 5 : 5;
}
this.setState({ cartItems: newItems }); // set new state
};
subtotalPrice = () => {
const { cartItems } = this.state;
if (cartItems) {
return cartItems.reduce(
(sum, item) =>
sum + (item.checked == 1 ? item.qty * item.salePrice : 0),
0
);
}
return 0;
};
render() {
const styles = StyleSheet.create({
centerElement: { justifyContent: "center", alignItems: "center" },
});
const { cartItems, cartItemsIsLoading, selectAll } = this.state;
return (
<View style={{ flex: 1, backgroundColor: "#f6f6f6" }}>
<View
style={{
flexDirection: "row",
backgroundColor: "#fff",
marginBottom: 10,
}}
>
<View style={[styles.centerElement, { width: 50, height: 50 }]}>
<Ionicons name="ios-cart" size={25} color="#000" />
</View>
<View style={[styles.centerElement, { height: 50 }]}>
<Text style={{ fontSize: 18, color: "#000" }}>Shopping Cart</Text>
</View>
</View>
{cartItemsIsLoading ? (
<View style={[styles.centerElement, { height: 300 }]}>
<ActivityIndicator size="large" color="#ef5739" />
</View>
) : (
<ScrollView>
{cartItems &&
cartItems.map((item, i) => (
<View
key={i}
style={{
flexDirection: "row",
backgroundColor: "#fff",
marginBottom: 2,
height: 120,
}}
>
<View style={[styles.centerElement, { width: 60 }]}>
<TouchableOpacity
style={[styles.centerElement, { width: 32, height: 32 }]}
onPress={() => this.selectHandler(i, item.checked)}
>
<Ionicons
name={
item.checked == 1
? "ios-checkmark-circle"
: "ios-checkmark-circle-outline"
}
size={25}
color={item.checked == 1 ? "#0faf9a" : "#aaaaaa"}
/>
</TouchableOpacity>
</View>
<View
style={{
flexDirection: "row",
flexGrow: 1,
flexShrink: 1,
alignSelf: "center",
}}
>
<TouchableOpacity
onPress={() => {
/*this.props.navigation.navigate('ProductDetails', {productDetails: item})*/
}}
style={{ paddingRight: 10 }}
>
<Image
source={{ uri: item.thumbnailImage }}
style={[
styles.centerElement,
{ height: 60, width: 60, backgroundColor: "#eeeeee" },
]}
/>
</TouchableOpacity>
<View
style={{
flexGrow: 1,
flexShrink: 1,
alignSelf: "center",
}}
>
<Text numberOfLines={1} style={{ fontSize: 15 }}>
{item.name}
</Text>
<Text numberOfLines={1} style={{ color: "#8f8f8f" }}>
{item.quantity}
</Text>
<Text numberOfLines={1} style={{ color: "#333333" }}>
₹{item.qty * item.salePrice}
</Text>
<Text>{item.status}</Text>
<View style={{ flexDirection: "row" }}>
<TouchableOpacity
onPress={() => this.quantityHandler("less", i)}
style={{ borderWidth: 1, borderColor: "#cccccc" }}
>
<MaterialIcons
name="remove"
size={22}
color="#cccccc"
/>
</TouchableOpacity>
<Text
style={{
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: "#cccccc",
paddingHorizontal: 7,
paddingTop: 3,
color: "#bbbbbb",
fontSize: 13,
}}
>
{item.qty}
</Text>
<TouchableOpacity
onPress={() => this.quantityHandler("more", i)}
style={{ borderWidth: 1, borderColor: "#cccccc" }}
>
<MaterialIcons name="add" size={22} color="#cccccc" />
</TouchableOpacity>
</View>
</View>
</View>
<View style={[styles.centerElement, { width: 60 }]}>
<TouchableOpacity
style={[styles.centerElement, { width: 32, height: 32 }]}
onPress={() => this.deleteHandler(i)}
>
<Ionicons name="md-trash" size={25} color="#ee4d2d" />
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
)}
{!cartItemsIsLoading && (
<View
style={{
backgroundColor: "#fff",
borderTopWidth: 2,
borderColor: "#f6f6f6",
paddingVertical: 5,
}}
>
<View style={{ flexDirection: "row" }}>
<View style={[styles.centerElement, { width: 60 }]}>
<View
style={[styles.centerElement, { width: 32, height: 32 }]}
></View>
</View>
<View
style={{
flexDirection: "row",
flexGrow: 1,
flexShrink: 1,
justifyContent: "space-between",
alignItems: "center",
}}
></View>
</View>
<View style={{ flexDirection: "row" }}>
<View style={[styles.centerElement, { width: 60 }]}>
<TouchableOpacity
style={[styles.centerElement, { width: 32, height: 32 }]}
onPress={() => this.selectHandlerAll(selectAll)}
>
<Ionicons
name={
selectAll == true
? "ios-checkmark-circle"
: "ios-checkmark-circle-outline"
}
size={25}
color={selectAll == true ? "#0faf9a" : "#aaaaaa"}
/>
</TouchableOpacity>
</View>
<View
style={{
flexDirection: "row",
flexGrow: 1,
flexShrink: 1,
justifyContent: "space-between",
alignItems: "center",
}}
>
<Text>Select All</Text>
<View
style={{
flexDirection: "row",
paddingRight: 20,
alignItems: "center",
}}
>
<Text style={{ color: "#8f8f8f" }}>SubTotal: </Text>
<Text>₹{this.subtotalPrice().toFixed(2)}</Text>
</View>
</View>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "flex-end",
height: 32,
paddingRight: 20,
alignItems: "center",
}}
>
<TouchableOpacity
style={[
styles.centerElement,
{
backgroundColor: "#0faf9a",
width: 100,
height: 25,
borderRadius: 5,
},
]}
onPress={() => console.log("test")}
>
<Text style={{ color: "#ffffff" }}>Add to Cart</Text>
</TouchableOpacity>
</View>
</View>
)}
</View>
);
}
}
export default Pulsars;

React Native Component NOT re-rendering

for some reason the component is not Re-Rendering on the setDependent, i have added the setPerson and the console does log the item without that one deleted, but is not updating the component. please see code below, as of right now is loading with no problem from the server but at the moment of deletion it does send the command to delete but the list does not get re-render, the "person" still listed on the FlatList
const RemoveDependent = ({ onPress }) =>
(
<TouchableWithoutFeedback onPress={onPress}>
<View style={{
backgroundColor: colors.dangerLight,
//height: 70,
width: 70,
//borderRadius: 35,
right:-5,
justifyContent: 'center',
alignItems: 'center'
}}>
<MaterialCommunityIcons name="trash-can" size={30} style={{ color: colors.white }} />
</View>
</TouchableWithoutFeedback>
)
function FamilyScreen(props) {
const [person, setDependent] = useState(dependents);
const handleRemove = onDependent => {
console.log(person.filter(d => d.id !== onDependent.id));
setDependent(person.filter((d) => d.id !== onDependent.id));
}
return (
<View style={{ backgroundColor: colors.white, flex: 1 }}>
<Image
source={require('../assets/familyBg.jpeg')}
style={styles.image}
resizeMode="cover"
/>
<View style={styles.details}>
<RevText style={styles.title}>Family Plan</RevText>
<RevText style={styles.description}>Description here</RevText>
</View>
<FlatList
data={dependents}
keyExtractor={personal => personal.id.toString()}
renderItem={({ item }) => (
<ListItem
onPress={() => handleRemove(item) }
title={item.name}
subTitle={item.type}
image={item.image}
renderRightActions={() => (<RemoveDependent onPress={() => handleRemove(item)} />) }
ItemSeparatorComponent={() => (<View style={{ width: '96%', left: 5, borderBottomColor: 'red', borderBottomWidth: 1 }} />)}
/>
)}
/>
</View>
);
}
Object {
"id": 1014,//REMOVED ID WHEN CLICKED
"image": 19,
"name": "Person 1",
"type": "Child",
}
Array [ //NEW ARRAY
Object {
"id": 1015,
"image": 19,
"name": "PERSON 2",
"type": "Child",
},
Object {
"id": 1016,
"image": 19,
"name": "PERSON 3",
"type": "Child",
},
Object {
"id": 1017,
"image": 19,
"name": "PERSON 4",
"type": "Child",
},
]
The main problem with this code is that your are altering a state object directly. You should treat all state objects as if they are immutable.
change
setDependent(person.filter((d) => d.id !== onDependent.id));
with
setDependent([...person.filter((d) => d.id != onDependent.id)]);

Unable to change state of Modal Reactnative

Code:
import React, { Component,useState } from 'react';
import {
StyleSheet,
View,
TouchableHighlight,
Text,
ToastAndroid,
ScrollView,
Modal,Button
} from 'react-native';
import ProgressCircle from 'react-native-progress-circle'
import AutoTags from 'react-native-tag-autocomplete';
import firebase from '../config';
import { TabView, SceneMap } from 'react-native-tab-view';
const db= firebase.database();
let itemsRef = db.ref('/dataset');
let input = db.ref('/tags');
let disease=[];
itemsRef.limitToFirst(10).on('value', (snapshot) => {
snapshot.forEach((childSnapshot) => {
disease.push(childSnapshot.val().Disease);
});
});
let addItem = item => {
input.push({
userSymptom: item
});
};
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
tagsSelected:[],
storedTags:[],
index: 0,
routes: [
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
{ key: 'third', title: 'Third'}],
modalVisible: false,
};
}
componentDidMount(){
let storedTags=[];
itemsRef.on('value', (snapshot) => {
snapshot.forEach((childSnapshot) => {
storedTags.push({'name':childSnapshot.val().Symptom});
});
});
let userSymptoms=[];
input.limitToLast(1).on('value', (snapshot)=>{
snapshot.forEach((childSnapshot)=>{
childSnapshot.val().userSymptom.forEach(element=>{
userSymptoms.push(element)
})
})
})
this.setState({ tagsSelected:userSymptoms})
this.setState({ storedTags: storedTags})
}
setModalVisible(visible){
this.setState({ modalVisible: visible });
}
Modal=()=>(
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {
console.log("Modal has been closed.");
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: "#2196F3" }}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
</View>
);
FirstRoute = () => (
<ScrollView style={[styles.container, { backgroundColor: '#ff4081' }]} >
{this.Modal()}
<TouchableHighlight style={styles.back} onPress={() => {
this.setModalVisible(true);
console.log('Pressed')
}}>
<View style={styles.DisEntry}>
<Text style={styles.text}>{disease[0]}</Text>
<ProgressCircle
percent={30}
radius={50}
borderWidth={8}
color="#3399FF"
shadowColor="#999"
bgColor="#fff"
>
<Text style={{ fontSize: 18 }}>{'30%'}</Text>
</ProgressCircle>
</View>
</TouchableHighlight>
</ScrollView>
);
SecondRoute = () => (
<View style={[styles.container, { backgroundColor: '#673ab7' }]}>
</View>
);
ThirdRoute = () => (
<View style={[styles.container, { backgroundColor: '#673ab7' }]}>
</View>
);
handleSubmit = () => {
addItem(this.state.tagsSelected);
ToastAndroid.show('Symptoms saved successfully', ToastAndroid.SHORT)
};
handleDelete = index => {
let tagsSelected = this.state.tagsSelected;
tagsSelected.splice(index, 1);
this.setState({ tagsSelected });
}
handleAddition = suggestion => {
this.setState({ tagsSelected: this.state.tagsSelected.concat([suggestion]) });
}
_handleIndexChange = index => this.setState({ index });
_renderScene = SceneMap({
first: this.FirstRoute,
second: this.SecondRoute,
third: this.ThirdRoute,
});
render() {
return (
<View style={styles.container}>
<View style={styles.row}>
<View style={styles.autocompleteContainer}>
<AutoTags
suggestions={this.state.storedTags}
tagsSelected={this.state.tagsSelected}
handleAddition={this.handleAddition}
handleDelete={this.handleDelete}
placeholder="Add a Symptom.." />
</View>
<TouchableHighlight
style={styles.button}
underlayColor="blue"
onPress={this.handleSubmit}>
<Text style={styles.buttonText}>Add</Text>
</TouchableHighlight>
</View>
<TabView
style={styles.tab}
navigationState={this.state}
renderScene={this._renderScene}
renderTabBar={this._renderTabBar}
onIndexChange={this._handleIndexChange}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
},
row:{
flexDirection:"row"
},
DisEntry:{
flexDirection:"row",
backgroundColor:'white',
borderColor: 'black',
borderWidth: 1,
borderRadius: 5,
padding: 2,
},
back:{
backgroundColor: 'blue'
},
text:{
flex:1,
},
button:{
flex:0,
backgroundColor:'white',
borderColor: 'black',
borderWidth: 1,
borderRadius: 5,
padding: 2,
justifyContent:'flex-end',
height:30,
justifyContent:'center',
},
autocompleteContainer: {
flex:1,
justifyContent:'flex-start',
marginBottom:10
},
tab:{
flex:1,
},
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: 22
},
modalView: {
margin: 20,
backgroundColor: "white",
borderRadius: 20,
padding: 35,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5
},
openButton: {
backgroundColor: "#F194FF",
borderRadius: 20,
padding: 10,
elevation: 2
},
textStyle: {
color: "white",
fontWeight: "bold",
textAlign: "center"
},
modalText: {
marginBottom: 15,
textAlign: "center"
}
});
I am facing the problem that i am unable to toggle the Modal visibility when i click the touchable highlight. Please tell me where is the issue in my code as when i change the state of my modalVisible to true the modal shows finely
.....................................................................................................
If i'm not mistaken Modal has to be inside of return()
class App extends Component {
state = {
modalVisible: false
};
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
render() {
const { modalVisible } = this.state;
return (
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: "#2196F3" }}
onPress={() => {
this.setModalVisible(!modalVisible);
}}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
<TouchableHighlight
style={styles.openButton}
onPress={() => {
this.setModalVisible(true);
}}
>
<Text style={styles.textStyle}>Show Modal</Text>
</TouchableHighlight>
</View>
);
}
}

How to create a drag and drop nested list in React Native

I am fairly new to React native, and I am looking for a way to have a Drag and Drop Nested List. Basically, I need to create a ToDo list divided in groups, in which the ToDos' order can be changed not only within groups but also among them. I managed to separatly create both a drag & drop list (using the "draggable Flatlist" components) and a nested list, but I am struggling in combining them.
Does anyone solved the issue or knows some kind of reusable component? Thank you.
Try the following:
import React, { useState, useCallback, Component } from 'react';
import { View, TouchableOpacity, Text, SafeAreaView, ScrollView } from 'react-native';
import DraggableFlatList, { RenderItemParams, } from 'react-native-draggable-flatlist';
const Goal_data = [
{
key: "0",
label: "Group",
backgroundColor: "#ababab",
},
{
key: "1",
label: "Group",
backgroundColor: "#ababab",
}
]
const Goal_data1 = [
{
key: "0",
label: "Task",
},
{
key: "1",
label: "Task",
}
]
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
data: Goal_data,
data1: Goal_data1,
scrollEnabled: true
}
}
onEnableScroll = (value) => {
this.setState({
enableScrollViewScroll: value,
});
}
renderItem1 = ({ item, index, drag, isActive }) => {
console.log('index', item)
return (
<TouchableOpacity
style={{
height: 70,
backgroundColor: isActive ? "blue" : item.backgroundColor,
alignItems: "center",
justifyContent: "center"
}}
onLongPress={drag}
>
<Text
style={{
fontWeight: "bold",
color: "white",
fontSize: 20
}}
>
{item.label}
</Text>
</TouchableOpacity>
);
};
plusdata = (data) => {
let d = this.state.data1;
const newRecord = {
key: "2",
label: "Task",
};
this.setState({
data1: [...d, newRecord]
})
}
render() {
return (
<SafeAreaView style={{ flex: 1, }}>
<ScrollView>
<View style={{ backgroundColor: 'aeaeae', flex: 1, paddingHorizontal: 30 }}>
<Text>Hello</Text>
<DraggableFlatList
data={Goal_data}
debug={true}
extraData={Goal_data}
keyExtractor={(item, index) => `draggable-item-${item.key}`}
//onMoveBegin={() => this.setState({ scrollEnabled: false })}
onDragEnd={({ data }) => this.setState({ data: data })}
renderItem={({ item, index, drag, isActive }) => {
console.log('index', item)
return (
<TouchableOpacity
style={{
backgroundColor: isActive ? "blue" : item.backgroundColor,
//alignItems: "center",
justifyContent: "center",
marginVertical: 20
}}
onLongPress={drag}
>
<View style={{ backgroundColor: 'aeaeae', borderColor: '#000', borderWidth: 1, paddingHorizontal: 30 }}>
<Text>{item.label}{index}</Text>
<DraggableFlatList
data={this.state.data1}
extraData={this.state.data1}
debug={true}
keyExtractor={(item, index) => `draggable-item-${index}`}
//onDragEnd={({ data }) => this.setState({ data: data })}
renderItem={({ item, index, drag, isActive }) => {
console.log('index', item)
return (
<TouchableOpacity
style={{
height: 30,
borderBottomWidth: 1,
backgroundColor: isActive ? "blue" : item.backgroundColor,
alignItems: "center",
justifyContent: "center"
}}
onLongPress={drag}
>
<Text
style={{
fontWeight: "bold",
color: "white",
fontSize: 20
}}
>
{item.label}{index}
</Text>
</TouchableOpacity>
);
}}
/>
<TouchableOpacity style={{ marginTop: 50, alignSelf: 'center' }} onPress={() => this.plusdata(Goal_data1)}>
<Text>Add</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>
);
}}
/>
</View>
</ScrollView>
</SafeAreaView>
)
}
}

can not use delete functionality in flatlist renderItem

Delete functionality is not working in flatlist renderItem method, but it will work perfectly fine if I use map function to render data instead of flatlsit.
Here is the sample code
class App extends Component {
state = {
todos: [
{ todo: 'go to gym', id: 1 },
{ todo: 'buy a mouse', id: 2 },
{ todo: 'practice hash table', id: 3 },
{ todo: 'iron clothes', id: 4 }
]
};
keyExtractor = item => item.id.toString();
handleDelete = id => {
const todos = this.state.todos.filter(item => item.id !== id);
this.setState({ todos });
};
renderItems({ item }) {
return (
<View
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between'
}}
>
<Text style={{ fontSize: 16 }}>{item.todo}</Text>
<TouchableOpacity
onPress={() => this.handleDelete(item.id)}
style={{ marginRight: 15 }}
>
<Text style={{ color: 'red' }}>Delete</Text>
</TouchableOpacity>
</View>
);
}
render() {
return (
<View>
{/* {this.renderItems()} */}
<FlatList
data={this.state.todos}
keyExtractor={this.keyExtractor}
renderItem={this.renderItems}
/>
</View>
);
}
}
I can't understand the reason it gives me the error _this2.handleDelete is not a function.
You were not binding your function, in your constructor bind the function or use array function
renderItems = ({ item }) => {
return (
<View
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Text style={{ fontSize: 16 }}>{item.todo}</Text>
<TouchableOpacity
onPress={() => this.handleDelete(item.id)}
style={{ marginRight: 15 }}>
<Text style={{ color: 'red' }}>Delete</Text>
</TouchableOpacity>
</View>
);
}