1

My component is a basic NavBar with different items. When Hovering over the item with the dopdiwn-items class, the NavBar should display those items in a block. Instead, only the first item can be seen, with the others being hidden. The same code, when put into plain HTML and CSS on code pen, works as expected. I discovered if I increase the size of the navbar then the items do show as a large block of text. I listed screenshots, and my code below.

CodePen link: http://codepen.io/anon/pen/dvNvmM

Parent Container:

/*Start dependencies*/
import React, { Component, PropTypes } from 'react';
import Picture from '../../components/picture.jsx';
import ShoppingCart from '../../components/shoppingcart.jsx';


import NavBar from '../../components/navbar.jsx';

import { browserHistory } from 'react-router';
import cart from '../../reducers/index.js';

/*Flag set to know if the client recieved and loaded
Will be set to True once the response from the server
Is loaded and parsed*/
var flag = true;


//Start React class
export default class Products extends Component {

    constructor(props) {
      super(props);
      this.state = {clothingData: 0}
    }



    render(){
    /*if the flag variable is false, server is not done yet retriving 
      data from the DB and parsing it, thus nothing displayed
    */
    if (!flag){ 
    return (
      <div>
      </div>
    );
    }
    //If flag is true (data is ready to be displayed)
    else{
        //console.log(this.state.clothingData[0].path);
        //console.log(this.state.clothingData[0].fileName);
        //console.log(this.state.clothingData);
        return (

            <div>

                <NavBar  />


        <Picture className = "test" src = {this.state.clothingData} onClick = { () => {browserHistory.push('/Product'); }} name = {"joe"} />

      </div>
    );
    }
 }

}

JSX:

import React, { Component, PropTypes } from 'react';
export default class NavBar extends Component {
    render(){

    return(


        <ul className="navbar">
         <li className="dropdown">
            <a href="#" className="dropdown-btn">Clothes</a>
            <div className="dropdown-items">  
              <a href="#">Item</a>
              <a href="#">Item</a>
              <a href="#">Item</a>
              <a href="#">Item</a>
            </div>  
        </li>
        <li>About</li>
        <li>Policies</li>
        <li>How To Rent</li>
        <li>Contact</li>  

         </ul>  

    );
  }
}

CSS:

/*Main HTML Stylesheet*/


html{
    font-family: sans-serif;
}

/*div{
    background:white;
}*/

/********* NavBar Section **********/
.navbar {
    overflow: hidden;
    background-color:#B597C3;
}

/* links inside the navigation bar */
.navbar li {
    float: left;
    display: block;
    color: #f2f2f2;
    text-align: center;
    padding: .625em 5em;
    text-decoration: none;
    font-size: 17px;
}

/* color of links on hover */
.navbar a:hover {
    color:#ffffff;
    text-decoration: underline;

}

.navbar a.active {
    text-decoration:underline;
}
/* Drop Down Items */
.dropdown-btn {
    float:left;
    font-size: 1.0625em;
    color:white;
    border: none;
    cursor: pointer;
    overflow:hidden;

}
.dropdown{

    display: inline-block;

}
.dropdown-items{
    position:absolute;
    display: none;
    margin:0;
    min-width: 10em;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);


}
.dropdown-items a {

    color:white;
    padding: 12px 50px;
    text-decoration: none;
    display: block;

}


.dropdown:hover .dropdown-items {
    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
}




/********* NavBar Section **********/

When Hovered: enter image description here

When Hovered w/ increased size: enter image description here

Justin E. Samuels
  • 867
  • 10
  • 28

1 Answers1

0

Okay, so I think you should not use CSS pseudo selectors with React. I've read questions like this one and my conclusion is in React you should handle the onMouseEnter and onMouseLeave events yourself and then keep a component state that indicates whether the dropdown should be shown or not.

That is the React way of usually doing things: hook up event handler functions and use the component state. When the handler functions are called, you change the state.

I don't know whether CSS pseudo selectors will work properly with React. You can take a look at this GitHub issue. My guess is that whatever you are trying to do doesn't work with the CSS selectors because React uses a virtual DOM and not the actual DOM. So the CSS would be changing the DOM directly kind of thing? It would be nice if other more knowledgeable people could comment on that.

For now, I think you should follow the React way of doing things. Here is the code for what you are trying to do:

import React, { Component, PropTypes } from 'react';

export default class NavBar extends Component {
  state = {
    showDropdown: false
  }

  renderDropdown() {
    return (
      <div className="dropdown-items">
        <a href="#">Item</a>
        <a href="#">Item</a>
        <a href="#">Item</a>
        <a href="#">Item</a>
      </div>
    );
  }

  render() {
    return (
      <ul className="navbar">
        <li
          className="dropdown"
          onMouseEnter={() => this.setState({ showDropdown: true })}
          onMouseLeave={() => this.setState({ showDropdown: false })}
        >
          <a href="#" className="dropdown-btn">Clothes</a>
          {this.state.showDropdown ? this.renderDropdown() : null}
        </li>
        <li>About</li>
        <li>Policies</li>
        <li>How To Rent</li>
        <li>Contact</li>
      </ul>
    );
  }
}

Keep in mind you should remove the CSS rule for the hover pseudo selector for the items div, as well as the display: none for the dropdown. After doing that, everything should be OK.

Note: I used a property initializer to set up the initial state for the component. Babel should take care of transpiling that. In case that doesn't work, set the initial state in the constructor.

Community
  • 1
  • 1
nbkhope
  • 7,360
  • 4
  • 40
  • 58
  • Well this is more of a styling/presentation issue because it does Render when styled with relative positioning, and another commentor above got it to work in Code Pen, so I think since mines is in a child, thats the issue – Justin E. Samuels Mar 09 '17 at 00:33
  • 1
    @JustinE.Samuels: Ok, sounds good. I feel like you could get more people interested in the question if you changed the title to include "when using CSS hover pseudo selector". That would also help other people someday in case they came across that issue. – nbkhope Mar 09 '17 at 00:53