我们或许不需要 classnames 这个库

3,874 阅读2分钟

项目许多库都不是必要的, 我们一个个移除, 今天先移除 classnames

使用 classNames 的情况:

import classNames from 'classnames';

export default ()=> {
  // className 的值: 'dog cat'
  return <div className={classNames('dog', {'cat':true, 'fish':false})} />
}

如果不使用classNames:

根据条件组合样式

export default ()=> {
  // className 的值: 'dog cat'
  return <div className={['dog', true && 'cat', false && 'fish'].filter(Boolean).join(' ')} />
}

有的童鞋会说, 参数太长了, 我们简化它

我们保留最后输出的 false 字符串, 为了减少浏览器查找 flase 样式的时间, 声明一个空的 .false css样式, 这样可以移除 filter(Boolean) 步骤:

// css
.false {}
export default ()=> {
  // className 的值: 'dog cat false'
  return <div className={['dog', true && 'cat', false && 'fish'].join(' ')} />
}

方案2, 仅使用字符串

这个方案的缺点是不够直观, 但是它的总长度更短

export default ()=> {
  // className 的值: 'dog cat false'
  return <div className={`dog ${true && 'cat'} ${false && 'fish'}`} />
}

如代码所述, 我们最后用了简单的一个语法就达到了目的, 简约便捷.

方案3, 简单封装

function names(obj) {
  let className = ''
  for(const k in obj) {
    className += obj[k] || ''
  }
  return className;
}

export default ()=> {
  // className 的值: 'dog cat'
  return <div className={names({dog: 1, cat: 0, fish: 1})} />
}

方案4, 让 className props 更短

这个方案不太推荐, 因为适应性不强

function names(obj) {
  let className = ''
  for(const k in obj) {
    className += obj[k] || ''
  }
  return { className };
}

export default ()=> {
  // className 的值: 'dog cat'
  return <div {...names({dog: 1, cat: 0, fish: 1})} />
}

性能如何?

运行 1w 次:

console.time('classnames');
range(10000).forEach(() => {
  classNames({ aa: true, bb: true, cc: false });
});
console.timeEnd('classnames'); 
//使用classnames, 1w次耗时: 12.334228515625ms

console.time('filter&join');
range(10000).forEach(() => {
  ['aa', true && 'bb', false && 'cc'].filter(Boolean).join(' ');
});
console.timeEnd('filter&join'); 
//使用filter和join, 1w次耗时: 9.76123046875ms

console.time('join');
range(10000).forEach(() => {
  ['aa', true && 'bb', false && 'cc'].join(' ');
});
console.timeEnd('join'); 
//仅使用join, 1w次耗时: 7.62060546875ms

如注释, 性能基本无区别, 使用 join(' ') 略好一些, 但是都可以忽略不计.

最后

# 记得移除此库 :)
$ yarn remove classnames