我非常喜欢React中的内联CSS模式,并决定使用它。

但是,你不能使用:hover和类似的选择器。那么,在使用内联CSS样式时实现高亮悬停的最佳方法是什么呢?

#reactjs的一个建议是有一个Clickable组件,并像这样使用它:

<Clickable>
    <Link />
</Clickable>

Clickable有一个悬停状态,并将其作为道具传递给链接。然而,Clickable(我实现它的方式)将链接包装在一个div中,以便它可以设置onMouseEnter和onMouseLeave。这让事情变得有点复杂(例如,在div中包装的span与span的行为不同)。

有没有更简单的方法?


当前回答

我认为onMouseEnter和onMouseLeave是可行的方法,但我不认为需要额外的包装器组件。以下是我如何实现它:

var Link = React.createClass({
  getInitialState: function(){
    return {hover: false}
  },
  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },
  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else {
      linkStyle = {backgroundColor: 'blue'}
    }
    return(
      <div>
        <a style={linkStyle} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>Link</a>
      </div>
    )
}

然后,您可以使用悬停状态(true/false)来更改链接的样式。

其他回答

这可以通过material-ui makestyle调用轻松实现:

import { makeStyles } from '@material-ui/core/styles';

makeStyles({
  root: {
    /* … */
    '&:hover': { /* … */ }
  },
});

我在我最近的一个应用程序中使用了一个相当hack的解决方案,它符合我的目的,我发现它比在香草js中编写自定义悬停设置函数更快(尽管,我承认,在大多数环境中可能不是最佳实践..)所以,如果你还感兴趣,我告诉你。

我创建了一个父元素,只是为了保存内联javascript样式,然后是一个带有className或id的子元素,我的css样式表将锁定并在我的专用css文件中写入悬浮样式。这是因为更细粒度的子元素通过继承接收内联js样式,但其悬停样式被css文件覆盖。

基本上,我的css文件存在的唯一目的就是保存悬停效果,没有别的。这使得它非常简洁,易于管理,并允许我在我的内联React组件样式中做繁重的工作。

这里有一个例子:

const styles = { container: { height: '3em', backgroundColor: 'white', display: 'flex', flexDirection: 'row', alignItems: 'stretch', justifyContent: 'flex-start', borderBottom: '1px solid gainsboro', }, parent: { display: 'flex', flex: 1, flexDirection: 'row', alignItems: 'stretch', justifyContent: 'flex-start', color: 'darkgrey', }, child: { width: '6em', textAlign: 'center', verticalAlign: 'middle', lineHeight: '3em', }, }; var NavBar = (props) => { const menuOptions = ['home', 'blog', 'projects', 'about']; return ( <div style={styles.container}> <div style={styles.parent}> {menuOptions.map((page) => <div className={'navBarOption'} style={styles.child} key={page}>{page}</div> )} </div> </div> ); }; ReactDOM.render( <NavBar/>, document.getElementById('app') ); .navBarOption:hover { color: black; } <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div>

注意,“child”内联样式没有“color”属性集。如果是这样,这将不起作用,因为内联样式将优先于样式表。

这可以是一个很好的hack内联样式在一个react组件(也使用:hover CSS函数):

...

<style>
  {`.galleryThumbnail.selected:hover{outline:2px solid #00c6af}`}
</style>

...

我做了类似的事情,但我没有使用material-ui或makestyle。我在样式对象的css中添加了悬停作为条件:

const styles = {
  hoverStyle: {
    color: 'grey',
    '&:hover': { color: 'blue !important' },
  }
};

var NavBar = (props) => {
  const menuOptions = ['home', 'blog', 'projects', 'about'];

  return (
    <div>
      <div>
        {menuOptions.map((page) => <div style={styles.hoverStyle} key={page}>{page}</div> )}
      </div>
    </div>
  );
};

这对我很管用。

我也有同样的情况。非常喜欢在组件中保持样式的模式,但悬停状态似乎是最后一个障碍。

我所做的是写一个mixin,你可以添加到你的组件,需要悬停状态。 这个mixin将为组件的状态添加一个新的悬停属性。如果用户将鼠标悬停在组件的主DOM节点上,它将被设置为true;如果用户离开元素,它将被设置为false。

现在在你的组件渲染函数中,你可以这样做:

<button style={m(
     this.styles.container,
     this.state.hovered && this.styles.hover,
)}>{this.props.children}</button>

现在,每当悬浮状态的状态发生变化时,组件将重新呈现。

我还为此创建了一个沙盒回购,我自己用它来测试这些模式中的一些。如果您想查看我的实现示例,请查看它。

https://github.com/Sitebase/cssinjs/tree/feature-interaction-mixin