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

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

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

<Clickable>
    <Link />
</Clickable>

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

有没有更简单的方法?


当前回答

在某种程度上是因为这个原因(其他原因是与其他库/语法的实现不一致,内联样式缺乏对前缀属性值的支持)。相信我们应该能够简单地用JavaScript编写CSS,并拥有完全自包含的组件HTML-CSS-JS。使用ES5 / ES6模板字符串,我们现在可以,而且它也可以很漂亮!:)

NPM install style-it -save

函数语法(JSFIDDLE)

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return Style.it(`
      .intro:hover {
        color: red;
      }
    `,
      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    );
  }
}

export default Intro;

JSX Syntax (j挑战者)

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        .intro:hover {
          color: red;
        }
      `}

        <p className="intro">CSS-in-JS made simple -- just Style It.</p>
      </Style>
    );
  }
}

export default Intro;

其他回答

我最近也遇到了同样的情况。这是我的一个非常简单的解决方案,使用一个自定义钩子,如果元素悬停或不悬停则返回。

export const useOnHover = (ref: React.RefObject) => {
    const [hovered, setHovered] = React.useState(false);

    const mouseEntered = React.useCallback(() => {
        setHovered(true);
    }, [ref.current]);

    const mouseLeft = React.useCallback(() => {
        setHovered(false);
    }, [ref.current]);

    React.useEffect(() => {
        if (!ref.current) return;

        ref.current.addEventListener("mouseenter", mouseEntered);
        ref.current.addEventListener("mouseleave", mouseLeft);

        return () => {
            if (!ref.current) return;
            ref.current.removeEventListener("mouseenter", mouseEntered);
            ref.current.removeEventListener("mouseleave", mouseLeft);
        };
    }, [ref.current]);

    return hovered;
};

现在你可以像这样在任何元素上使用它:

const Button = (props) => {
    const buttonRef = React.useRef(null);

    const buttonHovered = useOnHover(buttonRef);
    return (
        <div
            ref={buttonRef}
            style={{
                //your styles
                backgroundColor: "red",
                filter: buttonHovered ? "saturate(100%)" : "saturate(50%)",
            }}
        >
            {props.title}
        </div>
    );
};

完全的CSS支持正是大量的CSSinJS库的原因,为了有效地做到这一点,你需要生成实际的CSS,而不是内联样式。此外,内联样式在大系统中的反应要慢得多。免责声明-我维护JSS。

对于styles -components和react-router v4,你可以这样做:

import {NavLink} from 'react-router-dom'

const Link = styled(NavLink)`     
  background: blue;

  &:hover {
    color: white;
  }
`

...
<Clickable><Link to="/somewhere">somewhere</Link></Clickable>

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

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

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

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

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

我不能100%确定这是否是答案,但这是我用来模拟CSS的技巧:带有颜色和图像的悬停效果。

`This works best with an image`

class TestHover extends React.PureComponent {
render() {
const landingImage = {     
"backgroundImage": "url(https://i.dailymail.co.uk/i/pix/2015/09/01/18/2BE1E88B00000578-3218613-image-m-5_1441127035222.jpg)",
"BackgroundColor": "Red", `this can be any color`
"minHeight": "100%",
"backgroundAttachment": "fixed",
"backgroundPosition": "center",
"backgroundRepeat": "no-repeat",
"backgroundSize": "cover", 
"opacity": "0.8", `the hove trick is here in the opcaity slightly see through gives the effect when the background color changes`
    }

  return (
    <aside className="menu">
        <div className="menu-item">
          <div style={landingImage}>SOME TEXT</div>
        </div>
    </aside>
      ); 
  }
}
ReactDOM.render(
    <TestHover />,
  document.getElementById("root")
);

CSS:

.menu {
top: 2.70em;
bottom: 0px;
width: 100%;
position: absolute;
}

.menu-item {
cursor: pointer;
height: 100%;
font-size: 2em;
line-height: 1.3em;
color: #000;
font-family: "Poppins";
font-style: italic;
font-weight: 800;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}

前徘徊

.menu-item:nth-child(1) {
color: white;
background-color: #001b37;
} 

在徘徊

.menu-item:nth-child(1):hover {
color: green;
background-color: white;
}

例如:https://codepen.io/roryfn/pen/dxyYqj?editors=0011