简体   繁体   English

为什么以及如何在 React 组件中使用类名实用程序?

[英]Why and how to use classnames utility in React components?

Could you please explain to me in a simple way what is the purpose of using Classnames utility in React code?您能否以简单的方式向我解释在 React 代码中使用Classnames实用程序的目的是什么? I've just read Classnames docs, but I still can't grasp what is the main reason to use it in code like so:我刚刚阅读了 Classnames 文档,但我仍然无法理解在代码中使用它的主要原因是什么:

import classnames from 'classnames';
[...]
render() {
  const { className } = this.props

  return (
    <div className={classnames('search', className)}>
      <div className="search-bar-wrapper">
        <form className="search-form" onSubmit={this.onSearch.bind(this)}>
          <div className="search-bar">
            <label className="screen-reader-only" htmlFor="header-search-form">Search</label> [...]

Full version of this code (jsx): https://jsfiddle.net/John_Taylor/j8d42m2f/2/此代码的完整版本(jsx): https ://jsfiddle.net/John_Taylor/j8d42m2f/2/

I don't understand what is going on this line of code:我不明白这行代码发生了什么:

<div className={classnames('search', className)}>

I've also read that ( how to use classnames library for React.js ) answer, but I still have problems with understanding my code snippet.我也读过那个( 如何为 React.js 使用类名库)的答案,但我在理解我的代码片段方面仍然有问题。

classnames library lets you join different classes based on different conditions in a simpler way. classnames库允许您以更简单的方式根据不同条件加入不同的classes

Suppose you have 2 classes of which one is going to get used every time but the second one gets used based on some condition.假设您有 2 个类,其中一个每次都会使用,但第二个类会根据某些条件使用。 So without classnames library you would something like this所以如果没有classnames库,你会像这样

render() {
  const classnames = 'firstClass';

  if (someCondition) {
    classnames += ' secondClass'
  }

  return(
   <input className={classnames} .. />
  );
}

But with classnames library you would do that in this way但是使用classnames库,你会这样做

render() {
  const classnames = {'firstClass', {'secondClass': someCondition}}
  return(
   <input className={classnames} .. />
  );
}

In your case, <div className={classnames('search', className)}> is equivalent to <div className={`search ${className}`}> .在您的情况下, <div className={classnames('search', className)}>等效于<div className={`search ${className}`}>

classnames is mainly useful when you have to deal with conditional classes. classnames主要在您必须处理条件类时有用。

If used the way you use it in your script classnames simply joins the strings you give it with spaces.如果使用您在脚本类名中使用它的方式,只需将您提供的字符串与空格连接起来。

const className = 'x';
const result = classnames('search', className);
// result == 'search x'

I think you should attempt reading the docs one more time, they are very clear.我认为您应该再读一遍文档,它们非常清楚。 Specifically, this part:具体来说,这部分:

So where you may have the following code to generate a className prop for a in React:因此,您可能有以下代码为 React 中的 a 生成 className 道具:

var Button = React.createClass({
  // ...
  render () {
    var btnClass = 'btn';
    if (this.state.isPressed) btnClass += ' btn-pressed';
    else if (this.state.isHovered) btnClass += ' btn-over';
    return <button className={btnClass}>{this.props.label}</button>;
  }
});

You can express the conditional classes more simply as an object:您可以将条件类更简单地表示为一个对象:

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>;
  }
});

The sole purpose of the library here is to remove the need of writing ugly code to dynamically add classes to something, and just use a consistent syntax instead.这里库的唯一目的是消除编写丑陋代码来动态添加类的需要,而只需使用一致的语法。

Another example:另一个例子:

var Button = React.createClass({
  render () {
    return <button className={this.props.foo ? 'bar' : 'baz' + this.props.bar ? 'baz' : 'foo'}>{this.props.label}</button>;
  }
});

That is really hard to read.这真的很难读。 There is a lot of code out there that looks similar to that.那里有很多看起来与此类似的代码。

Here is a better way, using classnames:这是一个更好的方法,使用类名:

var classes = classNames({
    bar: this.props.foo,
    baz: !this.props.foo,
    active: this.props.bar,
    hover: !this.props.bar
});

var Button = React.createClass({
  render () {
    return <button className={classes}>{this.props.label}</button>;
  }
});

It's very clear there what's happening.很清楚那里发生了什么。 If the values in the object are true, the key will be appended to the class.如果对象中的值为真,则键将附加到类中。 So in that example, the final class will be bar active , given this.props.foo is truthy and this.props.bar is truthy.所以在那个例子中,最终的类将是bar active ,因为this.props.foo是真实的,而this.props.bar是真实的。

Your code snippet你的代码片段

<div className={classnames('search', className)}>

is equivalent to:相当于:

<div className={`search ${className ? className : ""}`}>

so in this particular case it's just encapsulates ternary operator from inside template string.所以在这种特殊情况下,它只是从模板字符串内部封装了三元运算符。 Which is small but improvement - harder to produce bug in.这是小但改进 - 更难产生错误。

Probably it is simplest case of using classnames , however when you'll have more and more conditions around your class name manipulations, it is going to be more and more useful可能是使用classnames最简单的情况,但是当您在类名操作周围有越来越多的条件时,它会越来越有用

Classnames make it easy to apply class names to react component conditionally.类名可以很容易地应用类名来有条件地反应组件。

For example: Let create a state and apply a class to the button component when the button is clicked例如:让我们创建一个状态,并在按钮被点击时将一个类应用到按钮组件上

const [isActive, setActive] = setState(false);
   import classnames from "classnames"
   var buttonClasses = classnames({
               "btn": true,
                "btn__active": isActive;
              )}
<button className={buttonClasses} onClick={() => setActive(!isActive)}>Make me active</button>

This code will apply the "isActive" class to the button when it is clicked.此代码将在单击按钮时将“isActive”类应用于按钮。 I hope this help answer your question我希望这有助于回答您的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM