我非常喜欢React中的内联CSS模式,并决定使用它。
但是,你不能使用:hover和类似的选择器。那么,在使用内联CSS样式时实现高亮悬停的最佳方法是什么呢?
#reactjs的一个建议是有一个Clickable组件,并像这样使用它:
<Clickable>
<Link />
</Clickable>
Clickable有一个悬停状态,并将其作为道具传递给链接。然而,Clickable(我实现它的方式)将链接包装在一个div中,以便它可以设置onMouseEnter和onMouseLeave。这让事情变得有点复杂(例如,在div中包装的span与span的行为不同)。
有没有更简单的方法?
我最近也遇到了同样的情况。这是我的一个非常简单的解决方案,使用一个自定义钩子,如果元素悬停或不悬停则返回。
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>
);
};
我不能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
这个解决方案确实使用了样式表。然而,如果你的应用程序使用了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/>
)
}
<Hoverable hoverStyle={styles.linkHover}>
<a href="https://example.com" style={styles.link}>
Go
</a>
</Hoverable>
其中Hoverable定义为:
function Hoverable(props) {
const [hover, setHover] = useState(false);
const child = Children.only(props.children);
const onHoverChange = useCallback(
e => {
const name = e.type === "mouseenter" ? "onMouseEnter" : "onMouseLeave";
setHover(!hover);
if (child.props[name]) {
child.props[name](e);
}
},
[setHover, hover, child]
);
return React.cloneElement(child, {
onMouseEnter: onHoverChange,
onMouseLeave: onHoverChange,
style: Object.assign({}, child.props.style, hover ? props.hoverStyle : {})
});
}