Eslint-plugin-react: It must be possible for ES6 defaultProps be equal to function execution

Created on 2 Jan 2019  路  16Comments  路  Source: yannickcr/eslint-plugin-react

In the class below:

class TestComponent extends React.Component {

    static defaultProps = function () {

       const date = new Date();

        return {
            date
        };
    }();
}

the defaultProps are equal to a anonymous function return value.

In this case, the eslint-plugin-react doesn't run, and throws the following error:
TypeError: Cannot read property 'split' of undefined at Object.isPropWrapperFunction (~/project/node_modules/eslint-plugin-react/lib/util/propWrapper.js:12:26) at resolveNodeValue (~/project/node_modules/eslint-plugin-react/lib/util/defaultProps.js:30:23) at Object.ClassProperty (~/project/node_modules/eslint-plugin-react/lib/util/defaultProps.js:222:26) at updatedRuleInstructions.(anonymous function) (~/project/node_modules/eslint-plugin-react/lib/util/Components.js:752:46) at listeners.(anonymous function).forEach.listener (~/project/node_modules/eslint/lib/util/safe-emitter.js:45:58)

I'm using the following versions:
"eslint": "5.10.0"
"eslint-plugin-react": "7.11.1".

If in the same class I put the defaultProps equal do an object it runs as expected.

Thanks

bug

Most helpful comment

Perfect, I'm able to repro.

All 16 comments

The rule definitely shouldn't crash - but static defaultProps can only ever be an object literal, not a function. The legacy createReactClass pattern is the one that had a function for things like that.

Can you update to v7.12.1 and see if it's still crashing?

Also, do you know what rule it's crashing on?

@ljharb this is an IIFE though, so it should still work out? Pretty rare case though and not something we can lint for IMO (shouldn't crash of course though).

Ah, I didn't even see that - yes, the IIFE should work fine wrt React.

I'm also getting this with latest

    "eslint": "5.11.1",
    "eslint-plugin-react": "7.12.1",

Setting this in .eslintrc.yaml is my work-around
react/forbid-prop-types: 0

ST:

> node ./node_modules/eslint/bin/eslint.js --ext .js,.jsx .
TypeError: Cannot read property 'split' of undefined
    at Object.isPropWrapperFunction (/project/node_modules/eslint-plugin-react/lib/util/propWrapper.js:12:26)
    at checkNode (/project/node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.js:128:31)
    at MemberExpression (/project/node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.js:158:9)
    at listeners.(anonymous function).forEach.listener (/project/node_modules/eslint/lib/util/safe-emitter.js:45:58)
    at Array.forEach (<anonymous>)
    at Object.emit (/project/node_modules/eslint/lib/util/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/project/node_modules/eslint/lib/util/node-event-generator.js:251:26)
    at NodeEventGenerator.applySelectors (/project/node_modules/eslint/lib/util/node-event-generator.js:280:22)
    at NodeEventGenerator.enterNode (/project/node_modules/eslint/lib/util/node-event-generator.js:294:14)
    at CodePathAnalyzer.enterNode (/project/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:632:23)

@jethrolarson by any chance, can you share the code that it's erroring on?

Stack trace doesn't say where the actual problem is, so I'm not sure. Code is proprietary so I can't just share the project.

The OP's test code doesn't crash on master.

@jethrolarson I understand. if you edit lib/rules/forbid-prop-types.js line 128 to console.log(context.getFilename()) (i think), it should print out the file at least?

@ljharb just throwing it out there - would it be impossible for eslint to set an uncaught exception handler that would make it easier for people to locate the source of crashes? We've been getting a lot of reports like this recently. (also sorry for having caused some of them with my changes)

I suppose we could; it'd be pretty intrusive to other plugins tho. It seems more like something eslint itself should be handing.

File with error (i think):

HeroTeaserList.propTypes = Object.assign({
    heroIndex: PropTypes.number,
    preview: PropTypes.bool,
}, componentApi, teaserListProps);

in another file

export const componentConfiguration = {
  childComponentMapping: objectOf(string),
  componentConfig: object,                
  componentInstanceId: string,            
  componentType: string,                  
  dataType: string,                       
  filter: shape(TemplateFilter),          
  filterVersionSetUuid: string,           
  teasers: arrayOf(shape(TeaserContent)), 
  title: string,                          
  titleOverride: node,                    
  uuid: string.isRequired,                
  visibleCount: number,                   
  epgUuid: string,                        
  readOnly: bool,                         
};

export const componentApi = Object.assign({
  getComponent: func.isRequired,
  onNavigation: func,
  onConfigurationChange: func,
}, componentConfiguration);

another file

export const teaserListProps = {
  'componentInstanceId': string,
  'title':               string.isRequired,
  'uuid':                string.isRequired,
  'data':                object,
  'listSize':            number,
  'priority':            number,
  'teasers':             arrayOf(shape(teaserProps)).isRequired,
  'visibleCount':        number,
};

Perfect, I'm able to repro.

@ljharb yeah that's what I meant there; just thought you might know why that could be unrealistic. I'll look around their issue tracker. 馃憤

This fails now even with the newest version 7.12.2:

RowSpanTable.propTypes = Object.assign({}, Table.propTypes, {
    propertyOrder: PropTypes.arrayOf(PropTypes.string).isRequired,
});

RowSpanTable.defaultProps = Object.assign({}, Table.defaultProps, {
    propertyOrder: [],
});

Table.propTypes = {
    pageOfItems: PropTypes.arrayOf(PropTypes.object).isRequired,
    onHeadlineClickedHandler: PropTypes.func.isRequired,
    sortByColumn: PropTypes.string.isRequired,
    getClassNameForHeadline: PropTypes.func.isRequired,
    headers: PropTypes.arrayOf(PropTypes.instanceOf(JSModelTableHeader)).isRequired, // array of JSModelTableHeader
    noItemFoundMessage: PropTypes.string.isRequired,
    rowClass: PropTypes.func.isRequired, // e.g. MetricRow
    rowProps: PropTypes.object.isRequired,
    rowItemKey: PropTypes.string.isRequired, // the key property of the item
};

Table.defaultProps = {
    pageOfItems: [],
};

Had to disable the PropTypes check for now.

@murphy1312 can you file a new issue?

Was this page helpful?
0 / 5 - 0 ratings