防止 React 卸载组件

Prevent React unmounted Component

我遇到此警告的性能问题:

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.

当我尝试登录时,我连接上了,但我没有被重定向到管理页面,我必须重新插入凭据才能进入管理页面。 这是登录组件的代码:

export class Login extends Component {
    _isMounted = false

    constructor(props) {
        super(props)
        this.state = {
            email: '',
            password: '',
            redirectToReferrer: false,
        }
    }

    componentDidMount() {
        this._isMounted = true
    }

    login() {
        const email = this.state.email
        const password = this.state.password
        axios.post(`${API_URL}login`, { email, password })
            .then((response) => {
                if (this._isMounted) {
                    this.setState({
                        redirectToReferrer: true
                    })
                    localStorage.setItem("tokens", JSON.stringify(response.data.token))
                    this.setState({
                        redirectToReferrer: true
                    })
                    console.log(localStorage.getItem('tokens'))
                }
                //alert(response.data.admin.email + " est connecté !")
            })
    }

    componentWillUnmount() {
        this._isMounted = false
    }

    render() {
        const { from } = this.props.location.state || { from: { pathname: '/admin' } }
        if (this.state.redirectToReferrer === true) {
            return <Redirect to={from} />
        }
        return (
            <>
                <PanelHeader size="sm" />
                <div className="content">
                    <Row>
                        <Col md="3"></Col>
                        <Col md="6">
                            <Card>
                                <CardHeader>
                                    <h1 className="title"
                                        style={{ textAlign: "center" }}
                                    >Login</h1>
                                </CardHeader>
                                <CardBody>
                                    <Form>
                                        <Row>
                                            <Col md="12">
                                                <FormGroup>
                                                    <h6>Email</h6>
                                                    <Input
                                                        placeholder="Email"
                                                        type="email"
                                                        required
                                                        onChange={(e) => {
                                                            var email = e.target.value
                                                            this.setState({ email: email })
                                                        }}
                                                    />
                                                </FormGroup>
                                            </Col>
                                        </Row>
                                        <Row>
                                            <Col md="12">
                                                <FormGroup>
                                                    <h6>Mot de passe</h6>
                                                    <Input
                                                        placeholder="Mot de passe"
                                                        type="password"
                                                        onChange={(e) => {
                                                            var password = e.target.value
                                                            this.setState({ password: password })
                                                        }}
                                                    />
                                                </FormGroup>
                                            </Col>
                                        </Row>
                                        <Row>
                                            <Col md="12">
                                                <FormGroup style={{ left: "40%" }}>
                                                    <Button outline color="info" size="lg"
                                                        onClick={this.login.bind(this)} className="btn-round">Login</Button>
                                                </FormGroup>
                                            </Col>
                                        </Row>
                                    </Form>
                                </CardBody>
                            </Card>
                        </Col>
                        <Col md="3"></Col>
                    </Row>
                </div>
            </>
        )
    }
}

我尝试使用 _isMounted 来解决这个问题,但它不起作用!

在我看来,您的第二个 setState 可能是导致此问题的原因:

if (this._isMounted) {
    this.setState({
        redirectToReferrer: true
    })
    localStorage.setItem("tokens", JSON.stringify(response.data.token))
    // try removing this second set state and see if it solves the issue
    // this.setState({
    //    redirectToReferrer: true
    // })
    console.log(localStorage.getItem('tokens'))
}

看起来第一个 setState 导致了重定向和卸载,因此当调用第二个 setState 时组件已经被卸载 - 因此出现错误。

也不清楚为什么您首先需要这两个 setState,因为它们都在进行相同的更改。