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

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

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

<Clickable>
    <Link />
</Clickable>

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

有没有更简单的方法?


当前回答

这是一个用typescript编写的通用hover包装器。该组件将在hover事件上应用通过props 'hoverStyle'传递的样式。

import React, { useState } from 'react';

export const Hover: React.FC<{
  style?: React.CSSProperties;
  hoverStyle: React.CSSProperties;
}> = ({ style = {}, hoverStyle, children }) => {
  const [isHovered, setHovered] = useState(false);
  const calculatedStyle = { ...style, ...(isHovered ? hoverStyle : {}) };
  return (
    <div
      style={calculatedStyle}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
    >
      {children}
    </div>
  );
};    

其他回答

我在我最近的一个应用程序中使用了一个相当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”属性集。如果是这样,这将不起作用,因为内联样式将优先于样式表。

聚会迟到了,但提出了解决方案。你可以使用“&”来定义悬停第n个子元素的样式。

day: {
    display: "flex",
    flex: "1",
    justifyContent: "center",
    alignItems: "center",
    width: "50px",
    height: "50px",
    transition: "all 0.2s",
    borderLeft: "solid 1px #cccccc",

    "&:hover": {
      background: "#efefef"
    },
    "&:last-child": {
      borderRight: "solid 1px #cccccc"
    }
},

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

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

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

这个解决方案确实使用了样式表。然而,如果你的应用程序使用了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>