Skip to content

Commit 8c61d14

Browse files
committed
Fix jsx-no-bind reporting errors on render functions that don't return
JSX (Fixes jsx-eslint#663)
1 parent ae27866 commit 8c61d14

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

lib/rules/jsx-no-bind.js

+20-6
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@
55
*/
66
'use strict';
77

8+
var Components = require('../util/Components');
89
var propName = require('jsx-ast-utils/propName');
910

1011
// -----------------------------------------------------------------------------
1112
// Rule Definition
1213
// -----------------------------------------------------------------------------
1314

14-
module.exports = function(context) {
15+
function renderReturnsJSX(node, utils) {
16+
var i = node.value.body.body.length - 1;
17+
for (; i >= 0; i--) {
18+
var testNode = node.value.body.body[i];
19+
if (testNode.type === 'ReturnStatement' && utils.isReturningJSX(testNode)) {
20+
return true;
21+
}
22+
}
23+
return false;
24+
}
25+
26+
module.exports = Components.detect(function(context, components, utils) {
1527
var configuration = context.options[0] || {};
1628

1729
return {
@@ -30,10 +42,12 @@ module.exports = function(context) {
3042
(ancestors[i].type === 'MethodDefinition' && ancestors[i].key.name === 'render') ||
3143
(ancestors[i].type === 'Property' && ancestors[i].key.name === 'render')
3244
) {
33-
context.report({
34-
node: callee,
35-
message: 'JSX props should not use .bind()'
36-
});
45+
if (renderReturnsJSX(ancestors[i], utils)) {
46+
context.report({
47+
node: callee,
48+
message: 'JSX props should not use .bind()'
49+
});
50+
}
3751
break;
3852
}
3953
}
@@ -74,7 +88,7 @@ module.exports = function(context) {
7488
}
7589
}
7690
};
77-
};
91+
});
7892

7993
module.exports.schema = [{
8094
type: 'object',

tests/lib/rules/jsx-no-bind.js

+35
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,29 @@ ruleTester.run('jsx-no-bind', rule, {
7272
].join('\n'),
7373
options: [{allowBind: true}],
7474
parser: 'babel-eslint'
75+
},
76+
// Backbone view with a bind
77+
{
78+
code: [
79+
'var DocumentRow = Backbone.View.extend({',
80+
' tagName: "li",',
81+
' render: function() {',
82+
' this.onTap.bind(this);',
83+
' }',
84+
'});'
85+
].join('\n'),
86+
parser: 'babel-eslint'
87+
},
88+
{
89+
code: [
90+
'const foo = {',
91+
' render: function() {',
92+
' this.onTap.bind(this);',
93+
' return true;',
94+
' }',
95+
'};'
96+
].join('\n'),
97+
parser: 'babel-eslint'
7598
}
7699
],
77100

@@ -121,6 +144,18 @@ ruleTester.run('jsx-no-bind', rule, {
121144
errors: [{message: 'JSX props should not use .bind()'}],
122145
parser: 'babel-eslint'
123146
},
147+
{
148+
code: [
149+
'const foo = {',
150+
' render: function() {',
151+
' const click = this.onTap.bind(this);',
152+
' return <div onClick={onClick}>Hello</div>;',
153+
' }',
154+
'};'
155+
].join('\n'),
156+
errors: [{message: 'JSX props should not use .bind()'}],
157+
parser: 'babel-eslint'
158+
},
124159

125160
// Arrow functions
126161
{

0 commit comments

Comments
 (0)