Currently working on an app this gives users lists of news on a page and on each news has a textbox where you can input your comment.
So for example, 10 news items will have 10 textboxes.
When a user comment after and hit the submit button, the activity indicator appears for all 10 news items, but I want it to only display on where the comment has been made and also after posting the comment, the comment box should be empty
Function
state = {
posts: [],
comment: ""
};
commentPost = item => {
const api = create({
baseURL: "patch-to-api-url",
headers: { Accept: "application/json" }
});
const self = this;
self.setState({ modalLoader: true });
api
.post("news/posts/" + `${item.id}` + "/comments", {
media: "",
text: this.state.comment
})
.then(response => {
console.log(response);
self.setState({ modalLoader: false });
//updating the state
this.setState(prevState => ({
posts: prevState.posts.map(el => {
if (el.id === item.id) {
return {
...el,
commentsCount: el.commentsCount + 1
};
}
return el;
})
}));
});
};
View
<ScrollView>
{posts.map((item, i) => {
return (
<View key={i} style={styles.user}>
<Card>
<ListItem
titleStyle={{ color: "#36c", fontWeight: "500" }}
onPress={() =>
navigation.navigate("PostComments", {
postID: item.id,
groupID: item.writer.group.id,
communityID: item.group.community.id
})
}
titleNumberOfLines={2}
hideChevron={false}
chevronColor="#36c"
roundAvatar
title={item.headline}
avatar={{
uri:
"https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg"
}}
/>
<Text
style={{
marginBottom: 10,
fontSize: 16,
color: "#000",
fontFamily: "HelveticaNeue-Light"
}}
>
{item.text}
</Text>
<TextInput
onChangeText={onSetComment}
label="Write Comment"
underlineColor="#36a"
style={{ backgroundColor: "#fff", width: "90%" }}
/>
<View>
<Icon
name="md-send"
type="ionicon"
color="#999"
onPress={() => {
onCommentPost(item);
}}
/>
<View style={styles.loading}>
<ActivityIndicator animating={modalLoader} size="small" />
</View>
</View>
</Card>
</View>
);
})}
</ScrollView>
2
Answers
You don’t have enough state to accomplish what you want. Wanting an independent spinner in each post implies that you have to store it’s state somewhere.
You should add the modalLoader attribute to each post and not globally. Change your function to look like this:
And your component to look like this:
You are sharing the modalLoader state among all iterated posts. A Post should be a single stateful component. Then for the specific component that was updated you need to update only that state.