Intellicode / eslint-plugin-react-native

React Native plugin for ESLint
MIT License
722 stars 130 forks source link

Crashing when using style prop that is a string #278

Closed DanielRamosAcosta closed 3 years ago

DanielRamosAcosta commented 3 years ago

Here is the crashing error:

ESLint: 7.20.0
TypeError: Cannot read property 'type' of undefined
Occurred while linting /myuser/myapp/src/screens/Walkthrough.tsx:82
    at JSXAttribute (/myuser/myapp/node_modules/eslint-plugin-react-native/lib/rules/no-single-element-style-arrays.js:40:35)
    at /myuser/myapp/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/myuser/myapp/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/myuser/myapp/node_modules/eslint/lib/linter/node-event-generator.js:256:26)
    at NodeEventGenerator.applySelectors (/myuser/myapp/node_modules/eslint/lib/linter/node-event-generator.js:285:22)
    at NodeEventGenerator.enterNode (/myuser/myapp/node_modules/eslint/lib/linter/node-event-generator.js:299:14)
    at CodePathAnalyzer.enterNode (/myuser/myapp/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:711:23)
    at /myuser/myapp/node_modules/eslint/lib/linter/linter.js:954:32
    at Array.forEach (<anonymous>)

This is caused because the StatusBar component from Expo has a style prop that can be auto, inverted, light, or dark. Here is the snippet where is crashing:

<StatusBar style="light" backgroundColor={COLORS.PRIMARY[500]} animated />

This, is not:

<StatusBar style={"light"} backgroundColor={COLORS.PRIMARY[500]} animated />
jaquinocode commented 3 years ago

Same exact problem for me. Crashes eslint.

Through trial and error I figured out that the bad rule that does this is: react-native/no-single-element-style-arrays

It also says the same in your error message, but just wanted to make it more clear.

And yes, it happens with Expo's status bar element that has a string for its style attribute.

andre-m5v commented 3 years ago

As a temporary workaround you could assign the style string to a variable:

const statusBarStyle = 'light';

and then use that as your style:

<StatusBar style={ statusBarStyle } />

This will prevent eslint from crashing. Then ofc you will get the react/style-prop-object rule error, but you can fix this by adding StatusBar as an exception in your rules.

AlanSl commented 3 years ago

The good news: this was fixed in this PR https://github.com/Intellicode/eslint-plugin-react-native/pull/262 which was merged in March 2021 https://github.com/Intellicode/eslint-plugin-react-native/commit/b908186ee3f4171c3e53deb1634e6831d61e0516

The bad news: the latest release, 3.10.0, was in September 2020, so the fix isn't yet available.

@Intellicode can you please publish a patch release to NPM? Thanks! [edit:] Sorry, just saw that you said on the PR you'd try to this weekend 🙌


Unfortunately the error seems to occur even if there's an eslint-disable for react-native/no-single-element-style-arrays, but this drop-in snippet fixes and explains it and ignores the lint errors resulting from the fix:

{/* eslint-plugin-react-native crashes on style="...", use style={'...'} */}
{/* https://github.com/Intellicode/eslint-plugin-react-native/issues/278 */}
{/* eslint-disable-next-line react/jsx-curly-brace-presence, react/style-prop-object */}
<StatusBar style={'light'} />
Intellicode commented 3 years ago

@AlanSl, just made a release, hope it works! If it breaks let me know.

AlanSl commented 3 years ago

@Intellicode Thanks! 3.11.0 works fine for me, looks like this (and the two linked duplicates just above) are fixed 🎉

Intellicode commented 3 years ago

@AlanSl thanks for your confirmation!

midrizi commented 2 years ago

@Intellicode Getting this error in VSCode in v4.0.0:

Eslint: v8.17.0

[Error - 1:47:05 PM] ESLint stack trace:
[Error - 1:47:05 PM] TypeError: Cannot read properties of null (reading 'expression')
Rule: "react-native/no-single-element-style-arrays"
    at JSXAttribute (/project/node_modules/eslint-plugin-react-native/lib/rules/no-single-element-style-arrays.js:40:25)
    at ruleErrorHandler (/project/node_modules/eslint/lib/linter/linter.js:1114:28)
    at /project/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/project/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/project/node_modules/eslint/lib/linter/node-event-generator.js:297:26)
    at NodeEventGenerator.applySelectors (/project/node_modules/eslint/lib/linter/node-event-generator.js:326:22)
    at NodeEventGenerator.enterNode (/project/node_modules/eslint/lib/linter/node-event-generator.js:340:14)
    at CodePathAnalyzer.enterNode (/project/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:795:23)
    at /project/node_modules/eslint/lib/linter/linter.js:1145:32