2

I have created dropdown onMouseOver with help of state. So far its working good enough. Because i don't have much knowledge about ReactJS i'm not sure is it possible to make multiple dropdowns with this or different method without writing all code over and over again.

Here is my code:

  ..........
  constructor(props) {
      super(props);
      this.handleMouseOver = this.handleMouseOver.bind(this);
      this.handleMouseLeave = this.handleMouseLeave.bind(this);
      this.state = {
        isHovering: false
      }
  }
  handleMouseOver = e => {
    e.preventDefault();
    this.setState({ isHovering: true });
  };
  handleMouseLeave = e => {
    e.preventDefault();
    this.setState({ isHovering: false })
  };

 ............

 <ul className="menu">
   <li onMouseOver={this.handleMouseOver} onMouseLeave={this.handleMouseLeave}>Categories
     {this.state.isHovering?(
       <ul className="dropdown">
         <li>Computerss & Office</li>
         <li>Electronics</li>
       </ul>
     ):null}
    </li>
  </ul>

 ............

So if I want to add one more dropdown I need to make new state and 2 more lines in constructor() and 2 functions to handle MouseOver/Leave.So repeating amount would be about this:

  constructor(props) {
      super(props);
      this.handleMouseOver = this.handleMouseOver.bind(this);
      this.handleMouseLeave = this.handleMouseLeave.bind(this);
      this.state = {
        isHovering: false
      }
  }
  handleMouseOver = e => {
    e.preventDefault();
    this.setState({ isHovering: true });
  };
  handleMouseLeave = e => {
    e.preventDefault();
    this.setState({ isHovering: false })
  };

I will have maybe 10+ dropdowns and at the end will be load of codes. So is there any possibility to not repeat code ? Thank You!

7
  • 1
    as answered, you just need to track the element you're hovering. this is possible using e.target.id...another example to achieve what you want jsfiddle.net/n5u2wwjg/152072 Commented Aug 24, 2018 at 21:04
  • @Elmer Dantas Thanks for your comment. I like your example, it is very simple and realy easy to use but it is not possible to move mouse over drodown window. Commented Aug 26, 2018 at 18:07
  • what do you mean by "over dropdown window"? Commented Aug 26, 2018 at 19:11
  • Sorry, my fault. Not sure what happened but first time when i loaded page i couldn't move mouse over "Computesrs & Office"/"Electronics". Loaded it again now its works perfect. Thank You gonna use this for my project, thank you very much ! Commented Aug 26, 2018 at 19:29
  • 2
    I've changed the code to work as I supposed it should and also post an answer as suggested by @SungKim. Hope it helps Commented Aug 26, 2018 at 23:19

2 Answers 2

3

You should use your event.target to achieve what you want. With this, you'll know which dropdown you're hovering and apply any logic you need. You can check for example if the dropdown you're hovering is the category dropdown like this:

if(e.target.className === "class name of your element")
this.setState({hoveredEl: e.target.className})

then you use it this state in your code to show/hide the element you want.

you can check an example on this fiddle I've created: https://jsfiddle.net/n5u2wwjg/153708/

I don't think you're going to need the onMouseLeave event, but if you need you can follow the logic I've applied to onMouseOver

Hope it helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you ! It helps a lot.
2

1. You need to save the state of each <li> item in an array/object to keep a track of hover states.

  constructor(props) {
    super(props);
    ...
    this.state = {
      hoverStates: {} // or an array
    };
  }

2. And set the state of each item in the event handlers.

handleMouseOver = e => {
    this.setState({
      hoverStates: {
        [e.target.id]: true
      }
    });
  };
  handleMouseLeave = e => {
    this.setState({
      hoverStates: {
        [e.target.id]: false
      }
    });
  };

3. You need to set the id (name doesn't work for <li>) in a list of menu items.

Also make sure to add key so that React doesn't give you a warning.

  render() {
    const { hoverStates } = this.state;
    const menuItems = [0, 1, 2, 3].map(id => (
      <li
        key={id}
        id={id}
        onMouseOver={this.handleMouseOver}
        onMouseLeave={this.handleMouseLeave}
        className={hoverStates[id] ? "hovering" : ""}
      >
        Categories
        {hoverStates[id] ? (
          <ul className="dropdown menu">
            <li>#{id} Computerss & Office</li>
            <li>#{id} Electronics</li>
          </ul>
        ) : null}
      </li>
    ));

    return <ul className="menu">{menuItems}</ul>;
  }

4. The result would look like this.

demo result


You can see the working demo here.

Edit p7xr8ro9jx


Shameless Plug

I've written about how to keep a track of each item in my blog, Keeping track of on/off states of React components, which explains more in detail.

4 Comments

Thank you for answer. It is working but it is not possible to move mouse over dropdown windows. And i dont see way how to change menu names separately. One name for all menus ?
If you need different menu names, you'd need to pass them as props to the component and use them within the map.
Okay i see. thank you ! I like @Elmer Dantas example more but because he did a comment instead of answering i think i will need to accept your answer.
@EdgarsŠusts I ping'ed Elmer in the question comment. Let's 🤞 that he post his comment as an answer so you can mark it so 😉

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.