Edgars Šusts
Edgars Šusts

Reputation: 111

Multiple dropdowns without repeating code in ReactJS

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!

Upvotes: 2

Views: 4306

Answers (2)

Elmer Dantas
Elmer Dantas

Reputation: 4849

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.

Upvotes: 3

dance2die
dance2die

Reputation: 36895

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.

Upvotes: 2

Related Questions