How to make an onClick function which is doing nothing? (React)

Hi there,

how can we make an onClick function which is doint nothing or which prevents that an HTML element (which has an onClick open/close function) will not get triggered?

In other words, I have an html overlay element which encloses all elements (login form) inside this overlay container, thats why the login form also closes when someone clicks inside the login form. But the form should just close when someone clicks outhside the login form (click on overlay), so I thought to make an onClick function which do nothing.

Is this the right way to create this onClick situation or is there a better option?

This is the example code:

import { useState } from 'react';

export default function LoginForm() {
  // OPEN AND CLOSE LOGIN FORM

  const [login, setLogin] = useState(false);

  const toggleLogin = () => {
    setLogin(!login);


  return (
    <>
      <button className="btn-login" onClick={toggleLogin}>
        Login
      </button>

      {login && (
        <div className="overlay" onClick={toggleLogin}>
              <div className="login-form_container" onClick={doNothing}>
                   <p>SOME CONTENT</p>
              </div>
        </div>
    )}
    </>
  );
}

Sould I set useState (true) ? I am sure it is not that complicated but I still dont understand the logic :sob:

Hope someone can help!!

If I understood you correctly, you might want to try including: event.stopPropagation() in your original form function to prevent the bubbling effect to your parent container element, so that it will only react to a click inside your intended element, not outside of that element (but in its parent element). Not also sure if it also works with react too though.
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

1 Like

Hello!

You have to check that the target is the current target of the event listener:

// Inside your event listener for when a user clicks on the overlay
if (e.target !== e.currentTarget) {
  // Returning false stops the execution of the event and prevents bubbling
  return false;
}

Take a look at this example and here you can see the source code.

1 Like

Thank you for your answers, I guess that´s the solution!

@skaparate the link in your answer is not working :frowning:

I have problems to figure out where to write the code… I guess I need to paste the event (e) as a parameter inside the () but then I need to tell the html element (which should not get triggered) that if there is a “click” execute the event, right?

What attribut I can use inside the button to link to the if statement?

Here again is the short code example:

import { useState } from 'react';

export default function LoginForm() {
  // OPEN AND CLOSE LOGIN FORM

  const [login, setLogin] = useState(false);

  const toggleLogin = () => {
    setLogin(!login);
  };

  return (
    <>
      <button className="btn-login" onClick={toggleLogin}>
        Login
      </button>

      {login && (
        <div className="overlay" onClick={toggleLogin}>
          <div className="login-form_container" ???attribute???>
          
          </div>
        </div>
      )}
    </>
  );
}

It would be great if someone could include the if statement:

// Inside your event listener for when a user clicks on the overlay
if (e.target !== e.currentTarget) {
  // Returning false stops the execution of the event and prevents bubbling
  return false;
}

into the code, I still dont know how to handle this …
:confounded:

1 Like

Inside your toggleLogin, just before the setLogin should be the if I mentioned.

The e, generally, stands for the event, which is the object passed to every event handler, like onClick. In other words, the toggleLogin already receives this event, you just have to declare it on the function parameters.

PD: I tested the links and they’re working, but here’s the code anyway:

import React, { useState } from 'react';
import './App.css';

function LoginForm(props) {
  const [showLogin, setShowLogin] = useState(false);

  function toggleLogin(e) {
    console.log('Event:', e);
    if (e.target !== e.currentTarget) {
      return false;
    }
    
    e.nativeEvent.stopImmediatePropagation();
    setShowLogin(!showLogin);
  }

  function doLogin() {
    console.log('Attempting to login');
  }

  let form = null;

  if (showLogin) {
    form = (
      <div className="overlay" onClick={toggleLogin}>
        <div className="login">
          <p>If you click anywhere outside of the gray area, the modal will close.</p>
          <label>User: <input type="text" /></label>
          <label>Pass: <input type="password" /></label>
          <button onClick={doLogin}>Enter</button>
        </div>
      </div>
    );
  }

  return (<div>
    <p>Click on the following button to display the modal:</p>
    <button onClick={toggleLogin}>Login</button>
    {form}
  </div>);
}

function App() {
  return (
    <main>
      <LoginForm />
    </main>
  );
}

export default App;
1 Like

i dont completely understand the desing you are after, but i think i worked on something similar. You can use the events onMouseEnter & onMouseLeave on the form and make them affect a boolean value which tells whether the mouse is over the form or not. The on click event of the overlay should have access to the boolean which tells if the mouse is over the form. If its over, it shouldnt to anything, if its not over the element, it should close the form.
PS: i think it would be appropriate to store the boolean inside a ref container(useRef()), to preserve value between renders. You should not store it as state because it would rerender components which wont be ideal for performance

@skaparate Thanks for the code example! It works exactly the way I need it. However your structure looks a little bit different then mine, so I need some time to think about the logic to be able to use it in my own code and actually learn something.

Oh yes and the link is working now, i dont know what was the issue before…

@Sylvant I guess that would not be the best way to do it in react, but maybe it would be a graet solution for plain Javascript.

1 Like