使用CSS hover伪选择器时,组件在React中无法正确渲染

时间:2017-03-08 23:19:46

标签: javascript css reactjs

我的组件是一个包含不同项目的基本NavBar。将鼠标悬停在具有dopdiwn-items类的项目上时,NavBar应在块中显示这些项目。相反,只能看到第一个项目,其他项目被隐藏。当在代码笔上放入纯HTML和CSS时,相同的代码按预期工作。我发现如果我增加导航栏的大小,那么项目会显示为一大块文本。我列出了截图,下面是我的代码。

CodePen链接:http://codepen.io/anon/pen/dvNvmM

父容器:

/*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 **********/

何时悬停: enter image description here

当盘旋增加时: enter image description here

1 个答案:

答案 0 :(得分:0)

好的,所以我认为你不应该在React中使用CSS伪选择器。我读过像this one这样的问题,我的结论是在React中你应该自己处理onMouseEnteronMouseLeave事件,然后保持一个状态的组件来指示是否应该显示下拉列表。

这是通常做事的React方式:挂钩事件处理函数并使用组件状态。调用处理函数时,可以更改状态。

我不知道CSS伪选择器是否能与React一起正常工作。你可以看看这个GitHub issue。我的猜测是,无论你想做什么都不能使用CSS选择器,因为React使用的是虚拟DOM,而不是实际的DOM。那么CSS会直接改变DOM的那种东西吗?如果其他知识渊博的人能对此发表评论,那就太好了。

目前,我认为你应该遵循React的做事方式。以下是您要执行的操作的代码:

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>
    );
  }
}

请注意,您应删除项目div的hover伪选择器的CSS规则,以及下拉列表的display: none。这样做之后,一切都应该没问题。

注意:我使用属性初始值设定项来设置组件的初始状态。巴别塔应该照顾好这一点。如果不起作用,请在构造函数中设置初始状态。