反应未安装的组件状态更新错误

时间:2020-06-24 14:02:52

标签: javascript reactjs

我的反应包括以下几个方面: PublicProfile.js:

import React, { Component } from 'react';
import axios from 'axios'
import Post from '../posts/Post'
import Navbar from '../Navbar'
import FollowButton from './FollowButton'
import { Avatar, Button, CircularProgress } from '@material-ui/core'

class PublicProfile extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            user: {},
            followers: undefined,
            following: undefined,
            posts: [],
            showFollowers: false,
            showFollows: false,
            curr_id: null
        }
        this.handleFollowerClick = this.handleFollowerClick.bind(this)
        this.handleFollowClick = this.handleFollowClick.bind(this)
    }
    componentDidMount() {
        const { user_id } = this.props.match.params
        axios.get(`http://127.0.0.1:8000/users/${user_id}`)
        .then(res => 
            this.setState({ 
                user: res.data,
                followers: res.data.followers.length, 
                following: res.data.following.length
            }))
        .catch(err => console.log(err))
        axios.get(`http://127.0.0.1:8000/posts/user/${user_id}`)
        .then(res => {
            this.setState({ posts: res.data })
        })   
        .catch(err => console.log(err))
        axios.get('http://127.0.0.1:8000/users/self')
        .then(res => this.setState({curr_id: res.data.id}))
        .catch(err => console.log(err))
    }
    handleFollowerClick(e) {
        e.preventDefault()
        if (this.state.showFollowers === true) {
            this.setState({showFollowers: false})
        } else {
            this.setState({showFollowers: true})
        }
    }
    handleFollowClick(e) {
        e.preventDefault()
        if (this.state.showFollows === true) {
            this.setState({showFollows: false})
        } else {
            this.setState({showFollows: true})
        }
    }
    render() {
        const showFollowers = this.state.showFollowers
        const showFollows = this.state.showFollows
        let followers
        let follows
        let edit
        let fbutton
        if (showFollowers === true) {
            followers = (
                <div>
                    <p>Followed by:</p>
                    <ul>
                        {this.state.user.followers.map(follower => (
                            <li key={follower.id}><a href={`/users/${follower.user.id}`}>{follower.user.username}</a></li>
                        ))}
                    </ul>
                </div>
            )
        }
        if (showFollows === true) {
            follows = (
                <div>
                    <p>Follows:</p>
                    <ul>
                        {this.state.user.following.map(follow => (
                            <li key={follow.id}><a href={`/users/${follow.user.id}`}>{follow.user.username}</a></li>
                        ))}
                    </ul>
                </div>
            )   
        }
        if (this.state.user.id === this.state.curr_id) {
            edit = <Button href='/profile'>Edit My Profile</Button>
        }
        if (this.state.user.id !== this.state.curr_id) {
            fbutton = <FollowButton user={this.state.user} followers_num={this.state.followers} setParentState={state => this.setState(state)} />
        }
        if (this.state.user.id !== undefined) {
            return ( 
                <div style={{background: '#f7f4e9'}}>
                    <Navbar />
                    <div style={{height: '70px'}}></div>
                    <div>
                        <Avatar style={{width: 75, height: 75}} variant='rounded' src={this.state.user.pp} alt={this.state.user.username} />
                        <h1>{this.state.user.username}</h1>
                        <h3>@{this.state.user.username}</h3>
                        <h4>{this.state.posts.length} Post(s)</h4>
                        <p>{this.state.user.bio}</p>
                        <Button style={{marginLeft: '10px'}} disabled={!this.state.following} onClick={this.handleFollowClick}>{this.state.following} Follows</Button>
                        <Button disabled={!this.state.followers} onClick={this.handleFollowerClick}>{this.state.followers} Followers</Button>
                        {followers}
                        {follows}
                    </div>
                    {edit}
                    {fbutton}
                    <div style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        flexDirection: 'column'
                    }}>
                        {this.state.posts.map(post => (
                            <Post key={post.id} post={post} />
                        ))}
                    </div>
                    <div style={{height: '15px'}}></div>
                </div>
            )
        } else {
            return (
            <div>
                <Navbar />
                <CircularProgress />
            </div>
            )
        }
    }
}
 

export default PublicProfile

FollowButton.js:

import React, { Component } from 'react';
import axios from 'axios'
import { Button } from '@material-ui/core'

class FollowButton extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            followsUser: null
        }
        this.unfollowClick = this.unfollowClick.bind(this)
        this.followClick = this.followClick.bind(this)
    }
    componentDidMount() {
        if (this.props.user.id !== undefined) {
            axios.get(`http://127.0.0.1:8000/users/check/${this.props.user.id}`)
            .then(res => {
                this.setState({ followsUser: res.data.follows })
            })
            .catch(err => console.log(err)) 
        }
    }
    unfollowClick() {
        axios.delete(`http://127.0.0.1:8000/users/${this.props.user.id}/unfollow/`)
        .then(() => {
            this.setState({ followsUser: false })
            this.props.setParentState({followers: this.props.followers_num - 1})
        })
        .catch(err => console.log(err))
    }
    followClick() {
        axios.post(`http://127.0.0.1:8000/users/${this.props.user.id}/follow/`)
        .then(res => {
            this.setState({ followsUser: true })
            this.props.setParentState({followers: this.props.followers_num + 1})
        })
        .catch(err => console.log(err))
    }
    // user: {
    //     followers: [...this.props.user.followers, res.data.user]
    // }
    render() { 
        let button
        if (this.state.followsUser) {
            button = <Button style={{background: 'blue'}} onClick={this.unfollowClick}>Following</Button>
        } else {
            button = <Button onClick={this.followClick}>Follow</Button>
        }
        return (
            <div style={{marginTop: '20px'}}>
                {button}
            </div> 
            
         );
    }
}

但是出现以下错误:

index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in FollowButton (at PublicProfile.js:93)

我发现此错误很大程度上是由于卸载组件时未解决的过程引起的,但是由于有条件,我什至在这种情况下甚至都没有渲染该组件,但是我似乎仍然会收到该错误。有人可以帮我解决这个问题。

2 个答案:

答案 0 :(得分:0)

卸载组件时,您不会取消axios请求。 Axios接受cancelToken作为参数,您应该创建一个提供方法CancelTokenSource的{​​{1}},然后在组件卸载时取消Source,从而取消所有待处理的请求。

答案 1 :(得分:0)

这是max的使用语法:

async/await