简体   繁体   English

子组件如何强制其父组件重新加载? 反应.js

[英]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.

相关问题 如何在其父组件之外渲染子组件(DOM Hierarchy) - React.js - How to render child component outside of its parent component (DOM Hierarchy) - React.js 如何通过道具[REACT.JS]将图片网址从父组件传递到子组件 - How can I pass image url from parent component to child component via props [REACT.JS] 在 REACT.js 中,如何将状态从子组件传递到父组件作为道具 - In REACT.js how can I pass a state from child component up to Parent component as a prop 如何在 React.JS 中将数据从子组件传递到父组件? - How to pass data from child to parent component in React.JS? 如何在React.JS中将状态从子组件传递给父组件? - How to pass state from child component to parent in React.JS? 如何在 react.js 中检测父组件中的子渲染 - How to detect child renders in a parent component in react.js 当父数据更改 Angular 4 时,如何强制子组件重新加载其数据及其视图 - How to force child component to reload its data and its view when parent data changes Angular 4 React.js:从其父类调用子组件函数/方法 - React.js: Call a child component function/method from its parent class 在React.js中从父组件调用子组件函数 - Calling Child component function from Parent component in React.js 在 React.js 中如何将数据从子组件传递到父组件 - How to pass data from a child component to a parent component in React.js
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM