[英]How can a child component force its parent to reload? React.js
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. TLTR:我希望子组件能够刷新整个父组件及其自己的子组件,以便它们在自己的 componentDidMount 函数中发出初始 http 请求。 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.
当调用props中给出的function时,我尝试在父组件中设置状态{...prevState} ,但它不会触发子组件的componentDidMount中的http请求,我什至认为它不会导致任何重新渲染。 I also tried this.forceUpdate() but that didn't work either.
我也试过this.forceUpdate()但这也没有用。
I have a parent component called LikesCommentsNumbers where I put the child components Like, Like (prop: dislike) and comment.我有一个名为 LikesCommentsNumbers 的父组件,我在其中放置了子组件 Like、Like (prop: dislike) 和评论。 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).
他们每个人都管理自己的 state 并发出 HTTP 请求以获取喜欢的数量以及是否应该填充喜欢的图标(这意味着用户已经喜欢了某些东西)。
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).按下喜欢/不喜欢时,会发出 HTTP 调用,其中喜欢的计数增加,不喜欢的计数减少(如果用户按下了喜欢按钮,反之亦然,如果他按下了不喜欢按钮)。
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.
我尝试以多种方式执行此操作,尝试在父组件中给定的子组件中执行 function,这将使父组件 setState {...prevState} 并希望也刷新所有子组件,但它没用。 This.forceUpdate also didn't work.
This.forceUpdate 也不起作用。 How can I make all the childrens' componentDidMount() [in which are my http requests] function to run again?
如何让所有孩子的 componentDidMount() [我的 http 请求] function 再次运行?
My component structure:我的组件结构:
[![enter image description here][1]][1] [![在此处输入图像描述][1]][1]
LikesCommentsNumbers: 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
create a new function in the parent component:在父组件中新建一个 function:
updateFromChild(){this.setState({//update whatever state you want}).
updateFromChild(){this.setState({//更新你想要的任何 state})。
Then when rendering the child component pass that function:然后在渲染子组件时传递 function:
Like refresh={this.state.LikeRefresh} objectIsBlog={this.props.objectIsBlog}... updateFromChild={this.updateFromChild}/>
像 refresh={this.state.LikeRefresh} objectIsBlog={this.props.objectIsBlog}... updateFromChild={this.updateFromChild}/>
In the child component when the like is hit or whenever u want to update the parent use在子组件中,当点击或当你想更新父组件时
this.props.updateFromChild() and it will update the whole parent component.
this.props.updateFromChild() 它将更新整个父组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.