TLTR: I want the child component to be able to refresh the entire parent component and it's own child components so that they make their initial http requests in their own componentDidMount functions. I tried to setState {...prevState} in the parent component when the function given in props is called, but it doesn't trigger the http requests in the componentDidMount of the children, and I don't even think that it causes any re render. I also tried this.forceUpdate() but that didn't work either.
I have a parent component called LikesCommentsNumbers where I put the child components Like, Like (prop: dislike) and comment. Each one of them manages its own state and makes a HTTP request to get the number of likes and if the like icon should be filled (which means that the user has already liked something).
Upon pressing the like/dislike a HTTP call is issued where the count of likes is incremented and the count of dislikes is decremented (if the user pressed the like button, and the other way around if he pressed the dislike button).
My point is, how to do the clean up?
When the user presses the like/dislike button I want the component to force the whole parent component to refresh / call for the data again. I tried to do it in many ways, trying to execute a function in the child component given in the props by the parent, that would make the parent component setState {...prevState} and hopefully refresh also all of the children, but it didn't work. This.forceUpdate also didn't work. How can I make all the childrens' componentDidMount() [in which are my http requests] function to run again?
My component structure:
[![enter image description here][1]][1]
LikesCommentsNumbers:
import axios from 'axios';
import { FaCommentAlt } from 'react-icons/fa';
import Like from '../UI/like';
import classes from './likesCommentsNumbers.module.css';
import getToken from '../../getToken';
class LikesCommentsNumbers extends Component {
constructor(props){
super(props);
let token = getToken();
this.state = {
objectId: props.objectId,
userId: props.userId,
token: token,
numberOfComments: 0,
LikeRefresh: false,
DislikeRefresh: false,
}
this.actionCleanUp.bind(this);
}
componentDidMount() {
if(this.props.comments){
axios({
method: 'post',
url: "http://localhost:3001/comments/getNumber",
headers: {'Authorization': this.state.token},
data: {
blogId: this.state.objectId
}
})
.then((res)=>{
if(res.status===200){
this.setState({numberOfComments: res.data.count});
return;
}
})
.catch(error => {
console.log(error);
})
}
}
actionCleanUp = (type) => {
this.setState((prevState) => {
return ({...prevState});
})
}
render() {
let commentIcon = null;
if(this.props.comments){
commentIcon = (
<div className={classes.iconDataContainer}>
<FaCommentAlt size="1em" color="#0a42a4" className={classes.icon}/>
<p>{this.state.numberOfComments}</p>
</div>
)
}
let dislikeclasses = classes.iconDataContainer;
if(!this.props.comments){
dislikeclasses = [classes.iconDataContainer, classes.movetoleft].join(" ")
}
let innerContainer = classes.numberInfoInnerContainer;
if(this.props.small){
innerContainer = [classes.numberInfoInnerContainer, classes.small].join(" ");
}
return (
<div className={classes.numberInfoContainer}>
<div className={innerContainer}>
<div className={[classes.iconDataContainer, classes.likeIconPContainer].join(" ")}>
<Like
refresh={this.state.LikeRefresh}
objectIsBlog={this.props.objectIsBlog}
token={this.state.token}
authorId={this.state.userId}
objectId={this.state.objectId}
cleanUp={this.actionCleanUp}
size="1.5em"
color="#0a42a4"
className={classes.icon}/>
</div>
<div className={dislikeclasses}>
<Like
refresh={this.state.DislikeRefresh}
dislike
objectIsBlog={this.props.objectIsBlog}
token={this.state.token}
authorId={this.state.userId}
objectId={this.state.objectId}
cleanUp={this.actionCleanUp}
size="1.5em"
color="#0a42a4"
className={classes.icon}/>
</div>
{commentIcon}
</div>
</div>
);
}
}
export default LikesCommentsNumbers;```
Like.js:
//componentDidMount:
componentDidMount(){
this.getData(); //http request to get number
this.handleFill(); //http request to check if liked already
}
//sendAction function:
sendAction = (like) => {
if(this.props.objectIsBlog){
let url = "http://localhost:3001/blogLike/upvote";
if(this.props.dislike) url = "http://localhost:3001/blogLike/downvote";
axios({
method: 'post',
url: url,
headers: {'Authorization': this.state.token},
data: { blogId: this.state.objectId }
})
.then((res)=>{
if(res.status===201 || res.status===200){
if(like){
this.props.cleanUp("like");
}
else {
this.props.cleanUp("dislike");
}
}
// this.setState({redirect: true})
// window.location.reload();
this.props.cleanUp();
})
.catch(error => {
console.log(error);
})
}
else{
let url = "http://localhost:3001/commentLike/upvote";
if(this.props.dislike) url = "http://localhost:3001/commentLike/downvote";
axios({
method: 'post',
url: url,
headers: {'Authorization': this.state.token},
data: { commentId: this.state.objectId }
})
.then((res)=>{
if(res.status===200){
this.setState((prevState) => {
return ({
...prevState,
number: res.data.count
})
})
}
})
.catch(error => {
console.log(error);
})
}
}
//render function:
let content;
if(this.props.dislike && this.state.DislikeFill){
content = <AiFillDislike
size={this.props.size}
color={this.props.color}
onClick={() => this.sendAction(false)}/>;
}
else if(this.props.dislike && !this.state.DislikeFill){
content = <AiOutlineDislike
size={this.props.size}
color={this.props.color}
onClick={() => this.sendAction(false)}/>;
}
else if(this.state.LikeFill){
content = <AiFillLike
size={this.props.size}
color={this.props.color}
onClick={() => this.sendAction(true)}/>;
}
else if(!this.state.LikeFill){
content = <AiOutlineLike
size={this.props.size}
color={this.props.color}
onClick={() => this.sendAction(true)}/>;
}
return (
<div className={classes.likeContainer}>
{content}
<p className={classes.likeP}>{this.state.number}</p>
</div>
);
[1]: https://i.stack.imgur.com/xjk3G.png