0

By the time the component is rendered, it seems componentDidMount has been called twice already and because the account has been verified already, different data is received from the server.
My problem is that I need my API Key to start a session and have different options coming from the server defined as booleans within an object for conditional rendering. The API key is received for only one of those options which is when I have just verified an account.
componentDidMount is called twice so the first time, I receive the API key, but not the second time. I tried using a conditional inside componentDidMount so the API call would be made once but state is emptied after the first time so it still gets called twice.

class Verify extends Component {
  state = {
    APIkey: '',
    token: '',
    userHasJustBeenActivated: false,
    newTokenCreated: false,
    userDeleted: false,
    userAlreadyActivated: false,
    errorMessage: '',
    dataWasFetched: false,
  }

  componentDidMount = () => {
    console.log('this.state.dataWasFetched :', this.state.dataWasFetched)
    if (this.state.dataWasFetched) {
      return 
    } else {
      console.log('location :', this.props.location)
      axios
        .get(`/api/auth/verify${this.props.location.search}`)
        .then(res => {
          console.log(JSON.stringify(res.data))
          const {
            APIkey,
            userHasJustBeenActivated,
            newTokenCreated,
            userDeleted,
            userAlreadyActivated,
          } = res.data
          this.setState({
            APIkey: APIkey,
            userHasJustBeenActivated: userHasJustBeenActivated,
            newTokenCreated: newTokenCreated,
            userDeleted: userDeleted,
            userAlreadyActivated: userAlreadyActivated,
            dataWasFetched: true,
          }, () => {
            if (APIkey) {
              cookies.setCookie('session', APIkey)
              console.log('this.state :', this.state)
              this.props.update()
            }
          })
        })
        .catch(err => {
          const { data } = err.response
          this.setState({
            errorMessage: data,
          })
        })
    }
  }

I tried adding a conditional with dataWasFetched so that the call to the API would only be made once but it seems that state is being emptied with each new call. When I check the console the value for state.dataWasFetchedis false and this.stateis not logged on the second call.

  • See [react and axios fires twice](https://stackoverflow.com/questions/40261284/react-and-axios-fires-twice-once-undefined-once-successfully/40261717) – awran5 Jan 30 '20 at 16:27
  • Yes, I know I can use conditional rendering to check for different axios responses, my problem is that I need my API Key to start a session and have different options coming from the server defined as booleans within an object for conditional rendering. The API key is received for only one of those options which is when I have just verified an account my problem is componentDidMount is called twice so the first time I receive the API key but not the second time I tried using a conditional inside componentDidMount so the API call would be made once but state is emptied after the first time. – Antonio Roldan Jan 30 '20 at 16:58
  • Can you show the result of `console.log(res.data)` inside `.then()`? – awran5 Jan 30 '20 at 18:15

1 Answers1

0

Indeed componentDidMount() is called twice if you setState in it, you wont be able to disable this.

The advices i can give you is to check if state.dataWasFetched is true before calling for the api, so your request towards the api is called only once, the first time.

You can also make your call in componentWillMount, but this is _UNSAFE so be carefull using it ! (not recommanded)

EDIT: If this do not do you should check where your Verify component is called. Maybe his parents is re-rendering and so calling the render of verify twice with initial state.

Palencar
  • 159
  • 12
  • I have added a conditional with ```state.dataWasFetched``` but the problem remains it seems that state is emptied after the first call to componentDidMount. – Antonio Roldan Jan 30 '20 at 16:44
  • Thats weird. Where is your component **Verify** called in your code? Are you sure its not his parents who is rendering twice, and so calling the creation of Verify twice with his initial state? – Palencar Jan 30 '20 at 17:00
  • **Verify** is called within a route in the App.js file it is used when the user clicks on a verification link that is sent in an email. – Antonio Roldan Jan 30 '20 at 17:02
  • Okay I solved it, the this.props.update method is defined in a parent component and I call setState within it so the parent component is re rendered I think that was the issue I solved it passing props to Verify from the parent component. – Antonio Roldan Jan 30 '20 at 17:50
  • glad to have been of some help ! would you mind tipping the response as answer as the answer is given (i edited the answer with the comments content to make it more clear and easy to find) ? :) – Palencar Jan 31 '20 at 08:33