Skip to content

Commit db5a243

Browse files
committed
Check if SFC is returning JSX or null
1 parent dfa5005 commit db5a243

File tree

2 files changed

+58
-16
lines changed

2 files changed

+58
-16
lines changed

lib/util/Components.js

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -303,14 +303,7 @@ function componentRule(rule, context) {
303303
return calledOnReact;
304304
},
305305

306-
/**
307-
* Check if the node is returning JSX
308-
*
309-
* @param {ASTNode} ASTnode The AST node being checked
310-
* @param {Boolean} strict If true, in a ternary condition the node must return JSX in both cases
311-
* @returns {Boolean} True if the node is returning JSX, false if not
312-
*/
313-
isReturningJSX: function(ASTnode, strict) {
306+
getReturnPropertyAndNode(ASTnode) {
314307
let property;
315308
let node = ASTnode;
316309
switch (node.type) {
@@ -321,19 +314,34 @@ function componentRule(rule, context) {
321314
property = 'body';
322315
if (node[property] && node[property].type === 'BlockStatement') {
323316
node = utils.findReturnStatement(node);
324-
if (!node) {
325-
return false;
326-
}
327317
property = 'argument';
328318
}
329319
break;
330320
default:
331321
node = utils.findReturnStatement(node);
332-
if (!node) {
333-
return false;
334-
}
335322
property = 'argument';
336323
}
324+
return {
325+
node: node,
326+
property: property
327+
};
328+
},
329+
330+
/**
331+
* Check if the node is returning JSX
332+
*
333+
* @param {ASTNode} ASTnode The AST node being checked
334+
* @param {Boolean} strict If true, in a ternary condition the node must return JSX in both cases
335+
* @returns {Boolean} True if the node is returning JSX, false if not
336+
*/
337+
isReturningJSX: function(ASTnode, strict) {
338+
const nodeAndProperty = utils.getReturnPropertyAndNode(ASTnode);
339+
const node = nodeAndProperty.node;
340+
const property = nodeAndProperty.property;
341+
342+
if (!node) {
343+
return false;
344+
}
337345

338346
const returnsConditionalJSXConsequent =
339347
node[property] &&
@@ -363,6 +371,35 @@ function componentRule(rule, context) {
363371
);
364372
},
365373

374+
/**
375+
* Check if the node is returning null
376+
*
377+
* @param {ASTNode} ASTnode The AST node being checked
378+
* @returns {Boolean} True if the node is returning null, false if not
379+
*/
380+
isReturningNull(ASTnode) {
381+
const nodeAndProperty = utils.getReturnPropertyAndNode(ASTnode);
382+
const property = nodeAndProperty.property;
383+
const node = nodeAndProperty.node;
384+
385+
if (!node) {
386+
return false;
387+
}
388+
389+
return node[property] && node[property].value === null;
390+
},
391+
392+
/**
393+
* Check if the node is returning JSX or null
394+
*
395+
* @param {ASTNode} ASTnode The AST node being checked
396+
* @param {Boolean} strict If true, in a ternary condition the node must return JSX in both cases
397+
* @returns {Boolean} True if the node is returning JSX or null, false if not
398+
*/
399+
isReturningJSXOrNull(ASTNode, strict) {
400+
return utils.isReturningJSX(ASTNode, strict) || utils.isReturningNull(ASTNode);
401+
},
402+
366403
/**
367404
* Find a return statment in the current node
368405
*
@@ -437,7 +474,7 @@ function componentRule(rule, context) {
437474
return null;
438475
}
439476
// Return the node if it is a function that is not a class method and is not inside a JSX Element
440-
if (isFunction && !isMethod && !isJSXExpressionContainer && utils.isReturningJSX(node)) {
477+
if (isFunction && !isMethod && !isJSXExpressionContainer && utils.isReturningJSXOrNull(node)) {
441478
return node;
442479
}
443480
scope = scope.upper;

tests/lib/rules/no-this-in-sfc.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ ruleTester.run('no-this-in-sfc', rule, {
3333
const { foo } = props;
3434
return <div bar={foo} />;
3535
}`
36+
}, {
37+
code: `
38+
function Foo({ foo }) {
39+
return <div bar={foo} />;
40+
}`
3641
}, {
3742
code: `
3843
class Foo extends React.Component {
@@ -58,7 +63,7 @@ ruleTester.run('no-this-in-sfc', rule, {
5863
settings: {react: {createClass: 'createClass'}}
5964
}, {
6065
code: `
61-
function Foo (bar) {
66+
function foo(bar) {
6267
this.bar = bar;
6368
this.props = 'baz';
6469
this.getFoo = function() {

0 commit comments

Comments
 (0)