首页 文章

ReactJS:无限循环渲染组件

提问于
浏览
0

我在ReactJS上遇到一个关于无限循环的Axios请求链接到componentDidMount函数的问题 .

这件事:

  • 第一:用户通过电子邮件接收链接(参数中带有令牌)

  • 第二:当他们点击链接时,他们到达了一个可以重置密码的网页 . 我需要检查令牌是否始终可用:取决于此,渲染将是不同的 .

为了检查令牌,我通过componentDidMount发出了POST请求 .

最后,我得到正确的渲染,但我的请求是一次又一次地调用,在我的服务器上创建一个无限循环 . 我的孩子组件似乎一次又一次地重建 .

这是我的代码:

子组件:

import React from 'react';
import {Container} from 'reactstrap';

export default class ResetPassword extends React.Component {

    constructor(props) {
        super(props);
        console.log('CONSTRUCT')
    }

    componentDidMount() {
if (this.props.appState.loading ≡ false) {
            console.log('componentDidMount')
            let url = window.location.pathname;
            let verifToken = url.substr(15);
            this.props.checkToken(verifToken); //Make axios call on App.js
        }
   }

    render() {
        const {expiredToken} = this.props.appState;
        console.log(expiredToken)
        return (
            <div className="ResetPassword">
                <Container>
                    {expiredToken === true ?
                        (<div>VOTRE TOKEN A EXPIRE</div>
                        ) : (<div>CHANGER MON MOT DE PASSE</div>)}
                </Container>
            </div>
        )
    }
}

父组件:

import axios from 'axios';
import ResetPassword from "./components/SignUp/ResetPwd";

class App extends React.Component {    
    constructor(props) {
        super(props);
        this.state = {
             loading: false,
             expiredToken : null
        };
        this.checkToken = this.checkToken.bind(this);
    }

    checkToken(token) {
        console.log('checkToken');
        this.setState({loading: true}, () => {
            let url = `${this.state.config.apiURL}/checkToken`;
            let method = 'post';
            axios.request({
                url: url,
                method: method,
                data: {
                    token: token
                }
            }).then(results => {
                if (results.data === null) {
                    this.setState({
                        loading: false,
                        expiredToken: true
                    })
                } else {
                    console.log(results.data);
                    this.setState({
                        loading: false,
                        expiredToken: false
                    });
                }
            })
        })
    }

    render() {
        const ResetPwd = (props) => {
            return (
                <div>
                    <ResetPassword appState={this.state} {...props} checkToken={this.checkToken}/>    
                </div>
            )
        };
    }
}

在我的控制台DevTool中,我有5个console.log(),它变成了一个无限循环:

  • CONSTRUCT - >来自child中构造函数的console.log()

  • expiredToken - > console.log()from render in child

  • ComponentDidMount→来自componentDidMount的console.log()

  • verifToken→来自componentDidMount的console.log()
    来自父级的

  • checkToken - > console.log()

2 回答

  • 1

    ResetPassword 组件中删除 checkToken .

    而不是从 ResetPassword 调用 checkToken ,而是在 Parent 组件中调用它并使用 state 将数据传递给 ResetPassword 组件 .

    <ResetPassword appState={...this.state} {...props}/>
    
  • 0

    我认为在你第一次加载childComponent并调用函数checkToken之后,状态加载被设置为false . 你也使用setSatate强制从parentcomponent重新渲染,并且你也强迫从子组件中加载Chilcomponent和componentDidMount方法 . 在第一次渲染之后,如果你试图打印加载状态,我确定它总是假的,在第一次真实之后 .

    尝试为每个孩子创建本地状态,或者再次考虑该功能的新实现 .

相关问题