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

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

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

<Clickable>
    <Link />
</Clickable>

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

有没有更简单的方法?


当前回答

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

我所做的是写一个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

其他回答

我认为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)来更改链接的样式。

你可以使用镭——它是一个开源工具,可以在ReactJS中使用内联样式。它恰好添加了您需要的选择器。非常受欢迎,看看npm上的镭

你可以创建一个抽象的悬停类,例如颜色。

.hoverClassColor:hover {
  color:var(--hover-color) !important;
}

然后在悬停时将所有元素的颜色更改为红色:

render() {
  return <a className={'hoverClassColor'} style={{'--hover-color':'red'}}>Test</a>
}

对我来说,它就像内联,因为类是抽象的,可以在你想实现颜色悬停的所有元素中重用。

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

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

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

补充乔纳森的回答,这里是事件覆盖的焦点和活跃状态,使用onMouseOver而不是onMouseEnter,因为后者不会冒泡,如果你有任何子元素的目标事件被应用到。

var Link = React.createClass({

  getInitialState: function(){
    return {hover: false, active: false, focus: false}
  },

  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },

  toggleActive: function(){
    this.setState({active: !this.state.active})
  },

  toggleFocus: function(){
    this.setState({focus: !this.state.focus})
  },

  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else if (this.state.active) {
      linkStyle = {backgroundColor: 'blue'}
    } else if (this.state.focus) {
      linkStyle = {backgroundColor: 'purple'}
    } 

    return(
      <div>
        <a style={linkStyle} 
          onMouseOver={this.toggleHover} 
          onMouseOut={this.toggleHover} 
          onMouseUp={this.toggleActive} 
          onMouseDown={this.toggleActive} 
          onFocus={this.toggleFocus}> 
          Link 
        </a>
      </div>
    )
  }