我非常喜欢React中的内联CSS模式,并决定使用它。
但是,你不能使用:hover和类似的选择器。那么,在使用内联CSS样式时实现高亮悬停的最佳方法是什么呢?
#reactjs的一个建议是有一个Clickable组件,并像这样使用它:
<Clickable>
<Link />
</Clickable>
Clickable有一个悬停状态,并将其作为道具传递给链接。然而,Clickable(我实现它的方式)将链接包装在一个div中,以便它可以设置onMouseEnter和onMouseLeave。这让事情变得有点复杂(例如,在div中包装的span与span的行为不同)。
有没有更简单的方法?
我做了类似的事情,但我没有使用material-ui或makestyle。我在样式对象的css中添加了悬停作为条件:
const styles = {
hoverStyle: {
color: 'grey',
'&:hover': { color: 'blue !important' },
}
};
var NavBar = (props) => {
const menuOptions = ['home', 'blog', 'projects', 'about'];
return (
<div>
<div>
{menuOptions.map((page) => <div style={styles.hoverStyle} key={page}>{page}</div> )}
</div>
</div>
);
};
这对我很管用。
我最近也遇到了同样的情况。这是我的一个非常简单的解决方案,使用一个自定义钩子,如果元素悬停或不悬停则返回。
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>
);
};
在某种程度上是因为这个原因(其他原因是与其他库/语法的实现不一致,内联样式缺乏对前缀属性值的支持)。相信我们应该能够简单地用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;
我认为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)来更改链接的样式。
onMouseEnter={(e) => {
e.target.style.backgroundColor = '#e13570';
e.target.style.border = '2px solid rgb(31, 0, 69)';
e.target.style.boxShadow = '-2px 0px 7px 2px #e13570';
}}
onMouseLeave={(e) => {
e.target.style.backgroundColor = 'rgb(31, 0, 69)';
e.target.style.border = '2px solid #593676';
e.target.style.boxShadow = '-2px 0px 7px 2px #e13570';
}}
在样式或类中设置默认属性,然后调用onMouseLeave()和onMouseEnter()来创建悬停功能。
这个解决方案确实使用了样式表。然而,如果你的应用程序使用了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/>
)
}