Classnames is a library that is used more frequently in corporate projects because of the ability to switch classnames dynamically.

Put a comparison we feel ~

<! -- before -->let clsName = 'conetnt'
    
if (showContent) {
  clsName += ' show'
} else {
  clsName += ' hide'
}
    
if (needMargin) clsName += ' add-margin'
    
return <div className={clsName} /><! -- after using classnames -->return <div className={classnames('content'{show: showContent.hide: !showContent, 'add-margin': needMargin})} / >
Copy the code

For encapsulated business components, the caller optionally passes in a custom classname, which looks like this with classnames:

// Assuming clsName is the custom class name passed in by the parent component, optional
<div className={classnames('self-classname', { [clsName]: !! clsName })} />Copy the code

Classnames above can dynamically select concatenated classnames based on the value TRULY, which is handy in front-end development.

Use of classNames has led to a growing curiosity: how does it work internally? 🤔

After viewing the source code on Github, I also learned something from 👍, and share it with you:

// Save the object hasOwnProperty method reference
var hasOwn = {}.hasOwnProperty
	
function classNames() {
  var classes = []

  for (var i = 0; i < arguments.length; i ++) {
    var arg = arguments[i]
    // Skip falsy
    if(! arg)continue

    var argType = typeof arg

    if (argType === 'string' || argType === 'number') {
      // If an argument is of type string or number, put it directly into the classes array
      classes.push(arg)
    } else if (Array.isArray(arg) && arg.length) {
      // If an argument is an array type, pass the argument in the array to classNames again and get the return value
      var inner = classNames.apply(null, arg)
      if (inner) classes.push(inner)
    } else if (argType === 'object') {
      if(arg.toString ! = =Object.prototype.toString) {
        // If an element has a custom toString method, call that method and store the return value to classes
        classes.push(arg.toString())
      } else {
        for (var key in arg) {
          // If an element is an object, traverse the key of that object, and put only the key that exists on the element itself and is not falsy into classes
          if (hasOwn.call(arg, key) && arg[key]) classes.push(key)
        }
      }
    }
  }

  // Return the concatenated class name
  return classes.join(' ')}Copy the code

Method Test screenshot:

Understanding the internal workings of the source code can make it clear when we use it how the results are produced, and which methods of use are not suitable, etc. ~ 🤗

— End —