haardikg
haardikg

Reputation: 29

React too many re renders infinite loop

I'm not sure why i'm getting this error, i'm just trying to make a button that inverts colors on hover, if you have a solution or a better way to do this please let me know

import React, {useState} from 'react'


function Login() {

  const [bttnColor, setBttnColor] = useState('white')
  const [textColor, setTextColor] = useState('black')

  function colorChange1(){
  setBttnColor('black')
  setTextColor('white')
  }
  function colorChange2(){
    setBttnColor('white')
    setTextColor('black')
    }

  return (
    <div className="Login" style={{display:'flex', flexDirection:'column', justifyContent:'center', alignItems:'center'}}>
     <h1 style={{display:'flex',  marginTop:'400px', marginBottom:'40px'}}>Login</h1>
    <input style={{height:'30px', width:'140px', marginBottom:'10px'}} placeholder='Username'/>
    <input style={{height:'30px', width:'140px'}} type='password'placeholder='Password'/>
    <button style={{height:'30px', width:'140px', marginTop:'10px', background:bttnColor, color:textColor}} onMouseEnter={colorChange1()} onMouseLeave={colorChange2()}>Login</button>:
    </div>
  )
}

export default Login

Upvotes: 1

Views: 624

Answers (1)

Mike Flynn
Mike Flynn

Reputation: 421

When declaring a property, the result of what's inside of the {} is sent to the Component.

This will send the result of colorChange1() to the component, not the function itself

onMouseEnter={colorChange1()} 

This is unwanted behavior in your use case, but remember that this is a property just like any other, like style or className.

You need to pass it a function reference instead of the result of the function. You can do that in two different ways:

onMouseEnter={colorChange1}
onMouseEnter={(event) => colorChange1(event, otherVariables...)}

The first way is a function reference to the existing function. Use this when you don't need to pass any other information to the function

The second way is to wrap the function call with a lambda. This will allow you to take variables from your current scope and pass them into the method when it's run.

EDIT:

On second thought, doing this at all is making it far more complicated than it needs to be. This can be done in a few lines of CSS.

Let's remove those color change methods and the onMouseEnter and onMouseLeave calls, and give the button a className so we can refer to it in CSS.

    <button className="login-button">Login</button>:

Then let's create the following css file, named Login.css in the same folder as Login.js:

.login-button {
  height: 30px;
  width: 140px;
  marginTop: 10px;
  background:white;
  color:black;
}
.login-button:hover {
  background: black;
  color: white;
}

Finally, let's import the css file:

import "./Login.css";

Upvotes: 4

Related Questions