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

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

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

<Clickable>
    <Link />
</Clickable>

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

有没有更简单的方法?


当前回答

直接在组件中使用标签,如下所示:

<Wrapper>
  <style>
   .custom-class{
       // CSS here
   }
   .custom-class:hover{
     //query selector
   }
  </style>
  <div className="custom-class"></div>
</Wrapper> 

其他回答

这可以通过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”属性集。如果是这样,这将不起作用,因为内联样式将优先于样式表。

使用钩子:

const useFade = () => {
  const [ fade, setFade ] = useState(false);

  const onMouseEnter = () => {
    setFade(true);
  };

  const onMouseLeave = () => {
    setFade(false);
  };

  const fadeStyle = !fade ? {
    opacity: 1, transition: 'all .2s ease-in-out',
  } : {
    opacity: .5, transition: 'all .2s ease-in-out',
  };

  return { fadeStyle, onMouseEnter, onMouseLeave };
};

const ListItem = ({ style }) => {
  const { fadeStyle, ...fadeProps } = useFade();

  return (
    <Paper
      style={{...fadeStyle, ...style}}
      {...fadeProps}
    >
      {...}
    </Paper>
  );
};

这个解决方案确实使用了样式表。然而,如果你的应用程序使用了index.css——也就是说,它有一个样式表被导入到你的顶级组件中,你可以只在那里写下面的代码

.hoverEffect:hover {
 //add some hover styles
}

然后在React组件中,添加类名“hoverEffect”来应用“内联”的悬停效果。

如果悬停状态是作为道具传递的,而你只想将它应用到子组件上,那么在index.css中删除:hover,并执行此操作。

function Link(props) {
  return (
    <a className={props.isHovered ? "hoverEffect" : ""}>Hover me<a/>
  )
}

签出类型样式,如果你使用React和Typescript。

下面是:hover的示例代码

import {style} from "typestyle";

/** convert a style object to a CSS class name */
const niceColors = style({
  transition: 'color .2s',
  color: 'blue',
  $nest: {
    '&:hover': {
      color: 'red'
    }
  }
});

<h1 className={niceColors}>Hello world</h1>