CSS in JS 很棒, 可是如何方便的处理伪类(Pseudo-classes)? react-dom-pseudo 提供一个相似 react-motion
方式的组件,方便的为 react-dom
对象提供相似 CSS 的伪类.css
咱们首先用 npm
安装:react
$ npm install --save react-dom-pseudo
复制代码
react-dom-pseudo 支持如下伪类:git
Props | 模拟伪类 | 说明 | 默认值 | 必须 |
---|---|---|---|---|
merge | 是否使用 style 和 其余状态的 style 进行合并 | true | 否 | |
disable | 是否取消事件监听 | false | 否 | |
style | 默认样式 | undefined | 否 | |
linkStyle | :link | 未被点击以前的样式 | undefined | 否 |
visitedStyle | :visited | 被点击过的样式 | undefined | 否 |
focusStyle | :focus | input 等类型元素 onFocus 时的样式 | undefined | 否 |
hoverStyle | :hover | 鼠标移入时显示的样式 | undefined | 否 |
activeStyle | :active | 鼠标或者触屏点击时的样式 | undefined | 否 |
disableStyle | 当取消事件监听时的样式 | undefined | 否 | |
alwayStyle | 会和全部样式合并,而且覆盖重复的样式属性 | undefined | 否 |
他们会根据事件的触发,和 style
合并返回, 如 {...style, ...activeStyle}
, 只有存在的样式会进行合并github
样式的组合规则: {...style, ...linkStyle, ...eventStyle, ...disableStyle, ...alwayStyle}
spring
import Pseudo from 'react-dom-pseudo';
export default () => {
return (
<div> <div>example:</div> <Pseudo style={sheet.input} hoverStyle={sheet.inputHover} focusStyle={sheet.inputFocus} > {events => <input {...events} />} </Pseudo> </div> ); }; // CSS in js const sheet = { input: { fontSize: '14px', border: '1px solid rgba(0,0,0,0)', background: '#f3f3f3', // 启用过渡动画 transition: 'all 0.2s ease-out', }, inputHover: { background: '#f0f0f0', }, inputFocus: { border: '1px solid rgba(0,0,0,0.1)', background: '#f0f0f3', transitionTimingFunction: 'ease-in', }, }; 复制代码
Pseudo 的 renderProps 中包含如下事件npm
若是项目在移动端执行,就会把 onMouse?
相关的事件替换成 onTouch?
以兼容移动端react-native
Input
组件有什么优点?咱们先看看若是咱们直接定义一个 Input 组件,来模拟 :hover 伪类数组
// 如下代码直接在 markdown 中编写,并没有通过运行,仅用于阐述观点
class Input extend React.Component {
state = {
hover: false
}
handleMouseEnter = ()=>{
this.setState({ hover: true });
}
handleMouseLeave = ()=>{
this.setState({ hover: false });
}
render(){
return <input style={this.state.hover?{...this.props.style, ...this.props.hoverStyle}:this.props.style} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} /> } } 复制代码
而后咱们在项目中使用:sass
<Input style={inputStyle} hover={inputHoverStyle} />
复制代码
一切看起来不错,可是它不利于扩展, 例如:咱们若是须要给一个 div
或 SignButton
也添加以上功能,咱们须要再写一个以上组件markdown
固然,咱们也能够使用 HOC 的方式, 编写一个 withHover
的组件, 即使如此,也须要在使用以前建立一个新的组件:
const SignButton = withHover(SignButton);
复制代码
对比之下,就没有 RenderProps
的方式优雅:
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{events => <input {...events} />} </Pseudo>
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{events => <div {...events} />} </Pseudo>
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{events => <SignButton {...events} />} </Pseudo>
复制代码
react-dom-pseudo
还能够更简化么?因为若是子对象是一个 div
或是一个 数组
时,以为使用 childrenFuncion
的意义不大,因此能够把简写:
// 能够简写成以下, 此时 Pseudo 是一个 div组件
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle} />
// 同理,多个子元素,也能够这样
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
<p>多个子元素</p>
<img src="xxx"/>
<div>父级至关于一个div</div>
</Pseudo>
复制代码
renderProps 的参数还有第二个,是 Pseudo
内部的 state
, 咱们能够获取它以后作其余事件, 以下面的例子,根据 hover 的状态咱们修改 div
的 innerText
,
state 有 4 个对象 { hover, focus, active, visited }
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{(events, state) => {
const mouseState = state.hover ? 'mouseIn' : 'mouseOut';
return <div {...events}>{mouseState}</div>;
}}
</Pseudo>
复制代码
Pseudo 把 disable
设置成 true
<Pseudo disable />
复制代码
Pseudo 有一个 alwayStyle
属性,最终返回的样式是这样的 {...style, ...otherStyle, ...alwayStyle}
<Pseudo alwayStyle={style} />
复制代码
因人而异,我以为比写 css
和 sass
更好一些,其缘由有如下几点:
react-motion
, react-spring
等,都会须要操做 style 对象, 它的样式可能分别会存在 css 和 js 中,此时就没有 CSS in JS 简洁;如何解决一些 CSS in JS 写起来麻烦的事情?
sass
的颜色混合等功能,能够使用 mix-color
之类的库轻松解决;sass
的自定义变量,在 CSS in JS 中能够很轻松的定义一个 globalStyles
对象达到;react-dom-pseudo
解决.react-dom-pseudo
支持 react-native
吗?因为 react-dom-pseudo
用到了 ReactDOM
的事件,因此不支持 react-native
, 有须要的朋友能够 fork 一份把DOM事件改为RN的 touchble
事件
最后,谢谢阅读:)