我曾经看到一篇文章说,其实现在的单页面应用已经有向feature-flag编程发展的倾向了.什么意思呢? 和鸿门宴一样,项羽设局为了杀刘邦,在大厅后面埋伏了刀斧手,这些刀斧手是否行动要等主人的指令,指令以来就行动. React中的state可以很好的完成这个flag功能.这就是状态编程.状态就两个true/false.根据true/false来决定状体的变化.可以根据状态的变化来决定是是否加载样式,或者是改变样式.
在React从Redux订阅了相关的State变化以后,组件的UI要相应的做出对用户操作的反馈,可以是某个子组件的展示/隐藏,某个css样式的变化.这个过程要是能动态化就好了.
最近看到几个app中使用了Classname这个组件,很好奇是干什么的,看了文档以后才发现这个组件能够提供很好的动态css样式功能,配合基于状态的编程,真是非常的便利.这里把文档安利一下.
安装
npm install classnames
使用方法
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
可以看到键值为true的就返回键名,可以利用这个方法来动态控制键值的true/fale变化,从而控制是否返回键.注意:默认是返回的
在ES2015中可以使用动态的classname
let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true });
React.js 中的使用
classnames结合React真是太美了
var Button = React.createClass({
// ...
render () {
var btnClass = 'btn';
//根据点击的state来控制css
if (this.state.isPressed) btnClass += ' btn-pressed';
else if (this.state.isHovered) btnClass += ' btn-over';
return <button className={btnClass}>{this.props.label}</button>;
}
});
可以统一返回一个对象
var classNames = require('classnames');
var Button = React.createClass({
// ...
render () {
var btnClass = classNames({
'btn': true,
'btn-pressed': this.state.isPressed,
'btn-over': !this.state.isPressed && this.state.isHovered
});
return <button className={btnClass}>{this.props.label}</button>;
}
});
如果是name和className进行了映射,可以使用bind方法
var classNames = require('classnames/bind');
var styles = {
foo: 'abc',
bar: 'def',
baz: 'xyz'
};
var cx = classNames.bind(styles);
var className = cx('foo', ['bar'], { baz: true }); // => "abc def xyz"
看看现实的使用例子
/* components/submit-button.js */
import { Component } from 'react';
import classNames from 'classnames/bind';
import styles from './submit-button.css';
let cx = classNames.bind(styles);
export default class SubmitButton extends Component {
render () {
let text = this.props.store.submissionInProgress ? 'Processing...' : 'Submit';//text根据状态来动态加载
let className = cx({
base: true,
inProgress: this.props.store.submissionInProgress,//样式的动态加载
error: this.props.store.errorOccurred,
disabled: this.props.form.valid,
});
return <button className={className}>{text}</button>;
}
};
Classnames真的是React/Redux的得力助手. 所以安利一下.