Reputation: 65
I have a react native screen that fetches a user's tickets from the database, then renders them in a flat list. I have two questions (that I repeat at the end).
Here is my class:
export default class MyEventsScreen extends Component {
state = {
tickets: [],
};
componentDidMount = () => {
fetch("http://127.0.0.1:8000/api/fullticket/?userID=4", {
method: "GET",
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
tickets: responseJson,
});
})
.catch((error) => {
console.error(error);
});
};
render() {
return (
<View>
<FlatList
style={{ flex: 1 }}
data={this.state.tickets}
renderItem={({ item }) => <Item item={item} />}
keyExtractor={(item) => item.ticketID}
/>
</View>
);
}
}
And here is the function I'm using to load each item of the FlatList:
function Item({ item }) {
return (
<View style={styles.listItem}>
<Image
source={{ uri: item.eventID.eventImage1 }}
/>
<View>
<Text>{item.eventID.artistName}</Text>
<Text>{item.eventID.eventName}</Text>
<Text>{item.ticketID}</Text>
</View>
<TouchableOpacity
onPress={() => deleteItem()}
>
<Text>x</Text>
</TouchableOpacity>
</View>
);
}
And here is a function I'm using to delete a given ticket from the server:
function deleteItem(ticketID) {
fetch("http://127.0.0.1:8000/api/ticket/" + ticketID, {
method: "DELETE",
}).catch((error) => {
console.error(error);
});
}
I have two questions:
Any help is hugely appreciated!
Upvotes: 0
Views: 1330
Reputation: 2604
For your first question: How do I pass {item.ticketID} to deleteItem()?
You can pass {item.ticketID}
to deleteItem()
like this:
function Item({ item }) {
return (
<View style={styles.listItem}>
<Image
source={{ uri: item.eventID.eventImage1 }}
/>
<View>
<Text>{item.eventID.artistName}</Text>
<Text>{item.eventID.eventName}</Text>
<Text>{item.ticketID}</Text>
</View>
<TouchableOpacity
onPress={() => deleteItem(item.ticketID)} // <=== This is how to pass the ticketId to your function deleteItem
>
<Text>x</Text>
</TouchableOpacity>
</View>
);
}
For your second question: How do I delete a given item from the State, so the list will automatically be updated?
You have to rename the function deleteItem
to handleDeleteItem
and move it up to your parent MyEventsScreen
because it's responsible for managing the state and the last step you have to pass the function to your component Item
via props:
Component MyEventsScreen:
export default class MyEventsScreen extends Component {
state = {
tickets: [],
};
componentDidMount = () => {
fetch("http://127.0.0.1:8000/api/fullticket/?userID=4", {
method: "GET",
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
tickets: responseJson,
});
})
.catch((error) => {
console.error(error);
});
};
handleDeleteItem = (ticketID) => {
fetch("http://127.0.0.1:8000/api/ticket/" + ticketID, {
method: "DELETE",
}).then(res => {
const {tickets} = this.state
const index = tickets.findIndex((ticket) => ticket.ticketID === ticketID);
const ticketsUpdated = [...tickets.slice(0, index), ...tickets.slice(index + 1)];
this.setState({tickets: ticketsUpdated })
}).catch((error) => {
console.error(error);
});
}
render() {
return (
<View>
<FlatList
style={{ flex: 1 }}
data={this.state.tickets}
renderItem={({ item }) => <Item item={item} deleteItem={this.handleDeleteItem} />} // <== This is how to pass the function handleDeleteItem to FlatList component
keyExtractor={(item) => item.ticketID}
/>
</View>
);
}
}
Component Item:
function Item({ item, deleteItem }) {
return (
<View style={styles.listItem}>
<Image
source={{ uri: item.eventID.eventImage1 }}
/>
<View>
<Text>{item.eventID.artistIName}</Text>
<Text>{item.eventID.eventName}</Text>
<Text>{item.ticketID}</Text>
</View>
<TouchableOpacity
onPress={() => deleteItem(item.ticketID)}
>
<Text>x</Text>
</TouchableOpacity>
</View>
);
}
Upvotes: 1
Reputation: 2393
Pass your deleteitem
function which you define in the parent component as a prop (like how you're passing item
) from parent context into the child Item
block. You can simply call in child as you have it and put item.ticketId
that you're already displaying in Item. It will work just fine to pass it into parent context. So your touchable opacity will be:
onPress={() => deleteItem(item.ticketId)}
In the parent deleteTicket
function you will have access to the state. Simply use whatever approach to filtering out the passes in ticketId
you like.
this.setState({
tickets: this.state.tickets.filter(/*...*/)
});
Also you may have to bind deleteItem
state to this
in parent constructor so it will be accessible when called from child. See this page for examples and explanation: https://reactjs.org/docs/faq-functions.html.
Upvotes: 0