Skip to content

Commit 49b7182

Browse files
p7gljharb
authored andcommitted
[Fix] jsx-no-bind: handle local function declarations
Fixes #3047
1 parent c66c073 commit 49b7182

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
2020
* [`no-typos`]: prevent crash on styled components and forwardRefs ([#3036][] @ljharb)
2121
* [`destructuring-assignment`], component detection: handle default exports edge case ([#3038][] @vedadeepta)
2222
* [`no-typos`]: fix crash on private methods ([#3043][] @ljharb)
23+
* [`jsx-no-bind`]: handle local function declarations ([#3048][] @p7g)
2324

2425
### Changed
2526
* [Docs] [`jsx-no-bind`]: updates discussion of refs ([#2998][] @dimitropoulos)
@@ -28,6 +29,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
2829
* [Docs] [`require-default-props`]: fix small typo ([#2994][] @evsasse)
2930
* [Tests] add weekly scheduled smoke tests ([#2963][] @AriPerkkio)
3031

32+
[#3048]: https://github.com/yannickcr/eslint-plugin-react/pull/3048
3133
[#3043]: https://github.com/yannickcr/eslint-plugin-react/issues/3043
3234
[#3039]: https://github.com/yannickcr/eslint-plugin-react/pull/3039
3335
[#3038]: https://github.com/yannickcr/eslint-plugin-react/pull/3038

docs/rules/jsx-no-bind.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Examples of **incorrect** code for this rule:
1414
```jsx
1515
<Foo onClick={() => console.log('Hello!')}></Foo>
1616
```
17+
```jsx
18+
function onClick() { console.log('Hello!'); }
19+
<Foo onClick={onClick} />
20+
```
1721

1822
Examples of **correct** code for this rule:
1923
```jsx
@@ -76,6 +80,11 @@ Examples of **correct** code for this rule, when `allowFunctions` is `true`:
7680
<Foo onClick={function () { alert("1337") }} />
7781
```
7882
83+
```jsx
84+
function onClick() { alert("1337"); }
85+
<Foo onClick={onClick} />
86+
```
87+
7988
### `allowBind`
8089
8190
Examples of **correct** code for this rule, when `allowBind` is `true`:

lib/rules/jsx-no-bind.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ module.exports = {
9696
if (!configuration.allowArrowFunctions && nodeType === 'ArrowFunctionExpression') {
9797
return 'arrowFunc';
9898
}
99-
if (!configuration.allowFunctions && nodeType === 'FunctionExpression') {
99+
if (
100+
!configuration.allowFunctions
101+
&& (nodeType === 'FunctionExpression' || nodeType === 'FunctionDeclaration')
102+
) {
100103
return 'func';
101104
}
102105
if (!configuration.allowBind && nodeType === 'BindExpression') {
@@ -144,6 +147,15 @@ module.exports = {
144147
setBlockVariableNameSet(node.range[0]);
145148
},
146149

150+
FunctionDeclaration(node) {
151+
const blockAncestors = getBlockStatementAncestors(node);
152+
const variableViolationType = getNodeViolationType(node);
153+
154+
if (blockAncestors.length > 0 && variableViolationType) {
155+
addVariableNameToSet(variableViolationType, node.id.name, blockAncestors[0].range[0]);
156+
}
157+
},
158+
147159
VariableDeclarator(node) {
148160
if (!node.init) {
149161
return;

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,19 @@ ruleTester.run('jsx-no-bind', rule, {
301301
code: '<div foo={::this.onChange} />',
302302
options: [{ignoreDOMComponents: true}],
303303
parser: parsers.BABEL_ESLINT
304+
},
305+
306+
// Local function declaration
307+
{
308+
code: [
309+
'function click() { return true; }',
310+
'class Hello23 extends React.Component {',
311+
' renderDiv() {',
312+
' return <div onClick={click}>Hello</div>;',
313+
' }',
314+
'};'
315+
].join('\n'),
316+
errors: []
304317
}
305318
],
306319

@@ -806,6 +819,21 @@ ruleTester.run('jsx-no-bind', rule, {
806819
parser: parsers.BABEL_ESLINT
807820
},
808821

822+
// Local function declaration
823+
{
824+
code: [
825+
'class Hello23 extends React.Component {',
826+
' renderDiv() {',
827+
' function click() { return true; }',
828+
' return <div onClick={click}>Hello</div>;',
829+
' }',
830+
'};'
831+
].join('\n'),
832+
errors: [
833+
{messageId: 'func'}
834+
]
835+
},
836+
809837
// ignore DOM components
810838
{
811839
code: '<Foo onClick={this._handleClick.bind(this)} />',

0 commit comments

Comments
 (0)