1

I have an url to confirm the account of my users, with a token in the url, after you enter into the page it should print you a message "User is now active" or "Token is not valid". In localhost it works perfect, but now in netlify it render the website but it does show any message either make any request to the server. Also It does not give me any type of error neither on the server nor on the frontend console.

here is the website link: https://cozy-melomakarona-5853fa.netlify.app/confirm-account/1g52cb94j2rke4pdlgl

my only suspicion is that the useEffect hook is not working in netlify.

import React, { useEffect, useState } from 'react'
import {useParams, Link} from "react-router-dom"
import Alert from '../components/Alert.jsx';

function Confirm() {

  const params = useParams();
  const {token} = params;
  const url = `${import.meta.env.VITE_BACKEND_URL}/api/veterinaries/confirm-account/${token}`;
  
  const [alert, setAlert] = useState({});
  const [confirmedAccount, setConfirmedAccount] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const confirmAccount = async ()=> {
      try {
        
        const response = await fetch(url);
        const result = await response.json();
        if (!response.ok){ //here we check if there is an error from the backend and we generate a new error with the message from backend
          throw new Error(result.msg);
        }
        
        //if everything is ok then
        setConfirmedAccount(true)
        setAlert({msg: result.msg, error1: false})
        
      } catch (error) {
        setAlert({msg: error.message, error1: true}) //here we show the backend error on the frontend
      }
      //stop loading
      setLoading(false);
    }
    
    return () => {
      confirmAccount();
    }
  }, [])
  


  const {msg} = alert;
  return (
    <>
      <div>
        <h1 className="text-indigo-600 font-black text-5xl text-center capitalize mr-6">
          Verify your account and <span className="text-black">manage your patients</span></h1>
      </div>
      <div className="shadow-lg rounded-xl bg-white px-5 py-10">
        {/* if it is not loading then show alert*/}
        {!loading ? <Alert alert={alert}/> : null }

         {/* if the account is confirmed then show sign in link*/}
        {confirmedAccount && <Link to="/" className="text-blue-600 block text-lg text-center mt-4">Sign in!</Link>}
      </div>
      
    </>
  )
}

export default Confirm
Albin Rdz
  • 143
  • 1
  • 11
  • Your `useEffect` call won't do anything until the component is torn down. The [documentation for `useEffect`](https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1) states: "*Why did we return a function from our effect? This is the optional cleanup mechanism for effects. Every effect may return a function that cleans up after it.*". So, do you intend to call `confirmAccount()` as part of the cleanup, when the component is torn down? ...or do you want to call it after first render?... in which case, just call `confirmAccount()`, don't return a function that calls it. – spender Jun 08 '22 at 20:22
  • I want to call it only after the first render, just once. if I do not return that function it make 2 request. – Albin Rdz Jun 08 '22 at 20:26
  • I commented more fully below. `StrictMode` is probably at play here. See https://stackoverflow.com/a/61897567/14357 and https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects – spender Jun 08 '22 at 20:50

1 Answers1

4

The way you are using useEffect is not the expected, return statement is unnecessary, instead you need to call your function confirmAccount, this should fix the issue:

const confirmAccount = async () => {
  try {
    const response = await fetch(url);
    const result = await response.json();
    if (!response.ok) {
      //here we check if there is an error from the backend and we generate a new error with the message from backend
      throw new Error(result.msg);
    }

    //if everything is ok then
    setConfirmedAccount(true);
    setAlert({ msg: result.msg, error1: false });
  } catch (error) {
    setAlert({ msg: error.message, error1: true }); //here we show the backend error on the frontend
  }
  //stop loading
  setLoading(false);
};

useEffect(() => {
  confirmAccount();
}, []);
Soufiane Boutahlil
  • 2,554
  • 1
  • 7
  • 13
  • 1
    if I do not return that function it make 2 request. – Albin Rdz Jun 08 '22 at 20:31
  • 1
    Now I realize if I dont return the function in the useEffect, in localhost it run twice, but in netlify it run once. Why is this happening on localhost? – Albin Rdz Jun 08 '22 at 20:40
  • 1
    Normally, it should be one call in dev & prod! – Soufiane Boutahlil Jun 08 '22 at 20:44
  • 1
    on local run twice, I test it with a console log, it get printed twice – Albin Rdz Jun 08 '22 at 20:48
  • 2
    @AlbinRdz That's because you [probably have `StrictMode` enabled](https://reactjs.org/docs/strict-mode.html) (it's there by default in a create-react-app setup). In dev, `StrictMode` will intentionally cause your component to be double-invoked. See [the docs](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects) and [this answer](https://stackoverflow.com/a/61897567/14357) for more info. – spender Jun 08 '22 at 20:48