Skip to content

Commit

Permalink
[Fix] jsx-no-bind: handle local function declarations
Browse files Browse the repository at this point in the history
Fixes #3047
  • Loading branch information
p7g authored and ljharb committed Aug 24, 2021
1 parent c66c073 commit 49b7182
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
* [`no-typos`]: prevent crash on styled components and forwardRefs ([#3036][] @ljharb)
* [`destructuring-assignment`], component detection: handle default exports edge case ([#3038][] @vedadeepta)
* [`no-typos`]: fix crash on private methods ([#3043][] @ljharb)
* [`jsx-no-bind`]: handle local function declarations ([#3048][] @p7g)

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

[#3048]: https://github.com/yannickcr/eslint-plugin-react/pull/3048
[#3043]: https://github.com/yannickcr/eslint-plugin-react/issues/3043
[#3039]: https://github.com/yannickcr/eslint-plugin-react/pull/3039
[#3038]: https://github.com/yannickcr/eslint-plugin-react/pull/3038
Expand Down
9 changes: 9 additions & 0 deletions docs/rules/jsx-no-bind.md
Expand Up @@ -14,6 +14,10 @@ Examples of **incorrect** code for this rule:
```jsx
<Foo onClick={() => console.log('Hello!')}></Foo>
```
```jsx
function onClick() { console.log('Hello!'); }
<Foo onClick={onClick} />
```

Examples of **correct** code for this rule:
```jsx
Expand Down Expand Up @@ -76,6 +80,11 @@ Examples of **correct** code for this rule, when `allowFunctions` is `true`:
<Foo onClick={function () { alert("1337") }} />
```
```jsx
function onClick() { alert("1337"); }
<Foo onClick={onClick} />
```
### `allowBind`
Examples of **correct** code for this rule, when `allowBind` is `true`:
Expand Down
14 changes: 13 additions & 1 deletion lib/rules/jsx-no-bind.js
Expand Up @@ -96,7 +96,10 @@ module.exports = {
if (!configuration.allowArrowFunctions && nodeType === 'ArrowFunctionExpression') {
return 'arrowFunc';
}
if (!configuration.allowFunctions && nodeType === 'FunctionExpression') {
if (
!configuration.allowFunctions
&& (nodeType === 'FunctionExpression' || nodeType === 'FunctionDeclaration')
) {
return 'func';
}
if (!configuration.allowBind && nodeType === 'BindExpression') {
Expand Down Expand Up @@ -144,6 +147,15 @@ module.exports = {
setBlockVariableNameSet(node.range[0]);
},

FunctionDeclaration(node) {
const blockAncestors = getBlockStatementAncestors(node);
const variableViolationType = getNodeViolationType(node);

if (blockAncestors.length > 0 && variableViolationType) {
addVariableNameToSet(variableViolationType, node.id.name, blockAncestors[0].range[0]);
}
},

VariableDeclarator(node) {
if (!node.init) {
return;
Expand Down
28 changes: 28 additions & 0 deletions tests/lib/rules/jsx-no-bind.js
Expand Up @@ -301,6 +301,19 @@ ruleTester.run('jsx-no-bind', rule, {
code: '<div foo={::this.onChange} />',
options: [{ignoreDOMComponents: true}],
parser: parsers.BABEL_ESLINT
},

// Local function declaration
{
code: [
'function click() { return true; }',
'class Hello23 extends React.Component {',
' renderDiv() {',
' return <div onClick={click}>Hello</div>;',
' }',
'};'
].join('\n'),
errors: []
}
],

Expand Down Expand Up @@ -806,6 +819,21 @@ ruleTester.run('jsx-no-bind', rule, {
parser: parsers.BABEL_ESLINT
},

// Local function declaration
{
code: [
'class Hello23 extends React.Component {',
' renderDiv() {',
' function click() { return true; }',
' return <div onClick={click}>Hello</div>;',
' }',
'};'
].join('\n'),
errors: [
{messageId: 'func'}
]
},

// ignore DOM components
{
code: '<Foo onClick={this._handleClick.bind(this)} />',
Expand Down

0 comments on commit 49b7182

Please sign in to comment.