YPCrumble
YPCrumble

Reputation: 28692

How can I deal with a long className in React JSX?

Let's say I'm rendering this component in React JSX:

render() {
  return (
    <h1 className="col-xs-6 col-xs-offset-3 col-md-4 col-md-offset-4 col-lg-2 col-lg-offset-5">Some text</h1>
  );
}

The classes trigger my JS linter as a line that's too long, and it's very hard to read. How can I separate a long className property in a React component into multiple lines without breaking JSX syntax or triggering a different error in a JS linter? (I'm using ESLint).

Upvotes: 13

Views: 7013

Answers (8)

foolo
foolo

Reputation: 958

The clsx libraray is a good option.

import { clsx } from 'clsx';

// ...

return (
    <h1 className={clsx(
        "col-xs-6",
        "col-xs-offset-3",
        "col-md-4",
        "col-md-offset-4",
        "col-lg-2",
        "col-lg-offset-5")}
    >
        Some text
    </h1>
)

Upvotes: 0

Lucien950
Lucien950

Reputation: 363

Use Backslashes

render() {
  return (
    <h1
      className="col-xs-6 col-xs-offset-3\
        col-md-4 col-md-offset-4 col-lg-2\
        col-lg-offset-5"
      >
        Some text
      </h1>
  );
}

Upvotes: 2

egiray
egiray

Reputation: 1209

You can use template literals

<div
className={`"card-body align-self-center d-flex flex-column
flex-md-row justify-content-between min-width-zero align-items-md-center"`}
>

Upvotes: -2

tapananand
tapananand

Reputation: 4862

I would suggest if there is some logic (decided based on some other values/props) to how the entire classname is decided you should use the classNames npm package.

However, in your case it seems that the class list is known to you already. In such a case, I tend to use Javascript template literals which allow a string to be split across multiple lines. Like this:

render() {
    return (
        <h1 className={`col-xs-6 col-xs-offset-3 col-md-4 col-md-offset-4 
            col-lg-2 col-lg-offset-5`}
        >
            Some text
        </h1>
    );
}

Upvotes: 3

Leonard Sch&#252;tz
Leonard Sch&#252;tz

Reputation: 526

I usually just wrap the strings to multiple lines and concatenate them. Don't forget to add spaces at the end or beginning of the strings.

So for your example it would be:

render() {
 return (
  <h1 className={
   'col-xs-6 ' +
   'col-xs-offset-3 ' +
   'col-md-4 ' +
   'col-md-offset-4 ' +
   'col-lg-2 ' +
   'col-lg-offset-5'}>Some text</h1>
 );
}

This way you it's also way easier to scan which classNames you have set.

Here is a great resource for some best-practice coding patterns, together with their respective ESLint or JSCS option.

Upvotes: 7

Marcel Mandatory
Marcel Mandatory

Reputation: 1447

@Imamudin Naseem solution with some code style improvements

I would suggest to improve code style and save classNames directly as a string

render() {
  const classNames = [
     'col-xs-6',
     'col-xs-offset-3',
     'col-md-4',
     'col-md-offset-4',
     'col-lg-2',
     'col-lg-offset-5'
  ].join(' ')

  return (
    <h1 className={classNames}>
      Some text
    </h1>
  );
}

Upvotes: 3

Imamudin Naseem
Imamudin Naseem

Reputation: 1702

Another Cleaner method will be to store the classNames in an array and join them.

render() { const classNames = ['col-xs-6', 'col-xs-offset-3', 'col-md-4', 'col-md-offset-4', 'col-lg-2', 'col-lg-offset-5'] return ( <h1 className={classNames.join(' ')}>Some text</h1> ); }

Upvotes: 11

Roman Pushkin
Roman Pushkin

Reputation: 6079

You can also use classNames:

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''

Maybe you can define some of your classes as variable, and reuse it.

Upvotes: 2

Related Questions