0

as soon as I go on to route /login in my web app it triggers an useEffect which it should not as no state has been changed at that point, please have a look at my code and tell me where am I wrong

function Login(){
const history = useHistory();

var [email, setEmail] = React.useState("");
var [password, setPassword] = React.useState("");
var [isLoggedIn, setLogin] = React.useState(false);
var [allTodosList, setList] = React.useState([]);

React.useEffect(()=>{
    console.log("triggered")
}, [isLoggedIn])

const sendLogin = async(event) => {
    try {
        var data = {
            Email : email,
            Password: password,
        }
        const response = await axios.post("/api/login", data);
        if (response.data.verified === true){
            const todoList = response.data.todos;
            setLogin(true);
        }
        else{
            alert("Invalid credentials please try again");
        }
    }
    catch(err){
        console.log("there is an error while sending login data via post");
        console.log(err);
    }
}
return(
    <div className = "login-form">
        <form>
            <input  
             type="text" className = "emailbox"
             placeholder = "Email" value = {email}
             onChange = {(event) => setEmail(event.target.value)}/>
            <input type="password" className = "passwordbox"
            name="password" id="password" 
            placeholder= "password" value = {password}
            onChange = {(event) => setPassword(event.target.value)}/>
            <span className = "login-button"><Button variant = "cantained"color = "secondary"
            onClick = {sendLogin}> Login</Button></span>
        </form>
    </div>
)
}
export default Login;

as I go on to this component using react route the useEffect gets triggered somehow and it console logs triggered.. please tell me how can I stop this useEffect from triggering unless the state is changed???

prasoonraj
  • 90
  • 9
  • All hooks run on the initial render. The `useEffect` hook is no different. The callback will be called. If there is some logic you *don't* want to run on the initial render then you can use a ref to hold a value that is toggled true after the first render. – Drew Reese May 06 '21 at 04:27

2 Answers2

1

It triggers on load and whenever the state changes. You should conditionally check the state.

React.useEffect(()=>{
    console.log("triggered")
    if (isLoggedIn) {
       console.log('isLoggedIn is true')
    }    
    //else, just don't do anything.

}, [isLoggedIn])

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined. https://reactjs.org/docs/hooks-effect.html

Which explains why useEffect is called when component is mounted, updated (base on dependency or empty array - called only once), and will be unmounted (cleanup).

Someone Special
  • 12,479
  • 7
  • 45
  • 76
0

Please look at this example. https://stackblitz.com/edit/react-eelqp2

I created a hook useMountedRef and check if mountedRef is true to avoid the side effect.

The reason why I used setTimeout is to make a reasonable delay so that we can make sure that the ref value is set to true after all initial useEffects.

Ever Dev
  • 1,882
  • 2
  • 14
  • 34