0

I have an issue on ReactJS about an infinite loop of an Axios request link to a componentDidMount function.

Here the thing :

  • First : user receive a link by email (with a token in parameter)
  • Second : When they clicked on the link, they arrived on a webpage where they can reset their password. I need to check if the token is always available : depending of that, the render will be different.

To check the token, I made a POST request via a componentDidMount.

Finally, I get the right render BUT my request is call again and again, creating an infinite loop on my server. It seems that my child component is re-construct again and again.

Here's my code :

Child component :

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>
        )
    }
}    

Parent Component :

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>
            )
        };
    }
}         

And in my console DevTool, I have my 5 console.log() which turn into an infinite loop :

  • CONSTRUCT --> console.log() from constructor in child
  • expiredToken --> console.log() from render in child
  • ComponentDidMount → console.log() from componentDidMount
  • verifToken → console.log() from componentDidMount
  • checkToken --> console.log() from parent

2 Answers 2

3

Remove checkToken from ResetPassword component.

Instead of calling checkToken from ResetPassword,called it within Parent component and pass the data using state to ResetPassword component..

  <ResetPassword appState={...this.state} {...props}/>
Sign up to request clarification or add additional context in comments.

2 Comments

OMG ! Thanks for you answer ! After some hours spent to understand where was my mistake, you solved my issue ! I move all code from ComponentDidMount (in child) to Parent and pass data has you told me ... It's work perfectly !
If I may : <ResetPassword appState={...this.state} {...props}/> I had to delete the '...' in {...this.state} to make it work
-1

i think after you load the childComponent for fist time and the function checkToken is called, the state loading is setted to false. you are also forcing a rerender from the parentcomponent with setSatate and with it you are forcing also the mounting from the Chilcomponent and the componentDidMount method from the child. after the first render if you try to print the loading state im sure it would be always false, after first true.

try to create local states for each child or think again a new implementation of the function.

1 Comment

Thanks for you're time and answer ! You're right, the way I think the code was not efficient, and surely created the loop !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.