eslint-plugin-react icon indicating copy to clipboard operation
eslint-plugin-react copied to clipboard

jsx-one-expression-per-line should ignore inline elements

Open anthonator opened this issue 6 years ago • 21 comments

It doesn't seem to make sense to one-line inline elements.

For example, one-lining the em element in the example below doesn't make sense.

<Styled.PasswordInstructions errored={ !!formErrors.userPassword }>
  Passwords must be at least 8 characters long and can&apos;t be
  things like <em>password</em>, <em>123456</em> or <em>abcdef</em>.
</Styled.PasswordInstructions>

Here is the "fixed" version.

<Styled.PasswordInstructions errored={ !!formErrors.userPassword }>
  Passwords must be at least 8 characters long and can&apos;t be
  things like
  <em>
    password
  </em>
  ,
  <em>
    123456
  </em>
  or
  <em>
    abcdef
  </em>
  .
</Styled.PasswordInstructions>

I could also see an option allowing the developer to choose which elements to ignore along with an ignoreInline option.

anthonator avatar Jun 25 '18 13:06 anthonator

In that particular case i agree it looks messy; I’m not sure how to generically allow it when it’s inline with text without having things like long links be inlined.

ljharb avatar Jun 25 '18 16:06 ljharb

Had a similar experience when bumping up to 7.10:

<h3><i className="fa fa-user" /> <strong>User</strong></h3>
{!!onClose && <button type="button" onClick={onClose}>Close</button>}
{!!onSave && <button type="submit" onClick={onSave}>Save</button>}

becomes

<h3>
  <i className="fa fa-user" />
  {' '}
  <strong>
    User
  </strong>
</h3>
{!!onClose && (
  <button type="button" onClick={onClose}>
    Close
  </button>
)}
{!!onSave && (
  <button type="submit" onClick={onSave}>
    Save
  </button>
)}

which are among the simpler of 100+ areas of code base that had to be changed. It's the simpler JSX though that should be able to be kept inline IMO.

I think maybe an inline option in conjunction with ESLint's max-len rule would be sufficient to handle things like long inline links, if that's doable?

I like the new rule and want to be able to enforce it in some way, but in its current state it's just overkill and actually has a negative impact on code appearance for what is essentially a purely stylistic rule.

ryansully avatar Jun 27 '18 22:06 ryansully

See #1855; I think they're related.

ljharb avatar Jun 27 '18 22:06 ljharb

Somewhat, but sort of a different concern. I left feedback there as well.

ryansully avatar Jun 27 '18 23:06 ryansully

@ljharb the reference to #1855 is confusing, because there you point back to this thread 😄

Mindaugas-Jacionis avatar Jul 11 '18 12:07 Mindaugas-Jacionis

@Mindaugas-Jacionis two things that relate to each other, cross-referencing each other, shouldn't be confusing.

ljharb avatar Jul 12 '18 07:07 ljharb

I recently had to disable react/jsx-one-expression-per-line because it made things like this much harder to read:

        <div>
            <span>ABC</span>
            { one && <span>DEF</span> }
            <span>GHI {two} JKL</span>
        </div>

Result:

        <div>
            <span>
                ABC
            </span>
            { one &&
                <span>
                    DEF
                </span>
            }
            <span>
                GHI
                {' '}
                {two}
                {' '}
                JKL
            </span>
        </div>

What I want to prevent is someone trying to inline nested tags. I don't care about people using <span>ABC</span> -- that's easy enough to read. I can understand why the lint rule current does what it does but it would be handy to have an option to ignore inlined non-tag expressions.

MrHen avatar Jul 31 '18 19:07 MrHen

Agreed. In addition, running --fix with this rule enabled completely mangles your code.

danny-andrews-snap avatar Sep 28 '18 21:09 danny-andrews-snap

I'm also very unhappy of Airbnb's style guide asking for that.

I have the exact same case:

            One or more rows have failed to process. Please use the filter option below to check
            which ones have failed and report it <strong>immediately</strong> to the engineering
            team.

I'm required to split up the <strong> part in a new line, which results in the necessity of having to add two more extra lines alongside with{' '} in order to preserve the whitespace.

I'm disabling it for now.

rdsedmundo avatar Oct 02 '18 14:10 rdsedmundo

This had messed up our pages with content. Text is missing meaningful spaces.

igorpupkinable avatar Feb 11 '19 16:02 igorpupkinable

Any update on this?

evenfrost avatar Apr 26 '20 16:04 evenfrost

See https://github.com/yannickcr/eslint-plugin-react/issues/1848#issuecomment-400011655

ljharb avatar Apr 27 '20 23:04 ljharb

This is very annoying... :disappointed:

Davidhidalgo avatar Sep 23 '20 15:09 Davidhidalgo

I recently had to disable react/jsx-one-expression-per-line because it made things like this much harder to read:

        <div>
            <span>ABC</span>
            { one && <span>DEF</span> }
            <span>GHI {two} JKL</span>
        </div>

Result:

        <div>
            <span>
                ABC
            </span>
            { one &&
                <span>
                    DEF
                </span>
            }
            <span>
                GHI
                {' '}
                {two}
                {' '}
                JKL
            </span>
        </div>

What I want to prevent is someone trying to inline nested tags. I don't care about people using <span>ABC</span> -- that's easy enough to read. I can understand why the lint rule current does what it does but it would be handy to have an option to ignore inlined non-tag expressions.

how did you that?

guiathayde avatar Nov 14 '20 01:11 guiathayde

Agree this can hinder readability and an allow inline option is needed. Disabling rule for now.

nomasprime avatar Dec 25 '20 13:12 nomasprime

At least tags like <b> and <em> should be ignored to start with...

nidalR avatar Apr 06 '21 17:04 nidalR

What's the solution? Add an option like ignoreElements: ['em', 'p'] and/or ignoreProps: ['key', 'whatever'] ?

TSMMark avatar Apr 06 '21 20:04 TSMMark

I'm not sure we have a solution yet - but it'd be great if someone wanted to propose one.

ljharb avatar Apr 06 '21 23:04 ljharb

@ljharb @TSMMark /* eslint-disable react/jsx-one-expression-per-line */ YOUR CODE.. /* eslint-enable react/jsx-one-expression-per-line */

misraelson avatar Mar 02 '22 11:03 misraelson

Great point, it's true that one of the best things about open source packages that other people wrote for you for free is that they are purely optional and you are not actually forced to use them! A lot of people don't know that. Thanks for notifying everyone subscribed to this thread with that valuable information!

Although I wouldn't recommend your approach for globally disabling an eslint rule across your entire codebase — you can simply add one line to your .eslintrc file inside the rules object, like:

"react/jsx-one-expression-per-line": 0

TSMMark avatar Mar 02 '22 16:03 TSMMark

I’m going to hide all three of these comments; disabling an eslint rule is well-understood and well-documented, and is in no way a “solution”.

ljharb avatar Mar 02 '22 18:03 ljharb