Skip to content

Commit

Permalink
no-render-return-value. closes jsx-eslint#531
Browse files Browse the repository at this point in the history
As documented initially in facebook/react#6400
and on the documentation website at
http://facebook.github.io/react/docs/top-level-api.html#reactdom.render
  • Loading branch information
iamdustan committed May 3, 2016
1 parent 63d33cb commit 00c0d73
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 0 deletions.
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = {
'no-deprecated': require('./lib/rules/no-deprecated'),
'no-did-mount-set-state': require('./lib/rules/no-did-mount-set-state'),
'no-did-update-set-state': require('./lib/rules/no-did-update-set-state'),
'no-render-return-value': require('./lib/rules/no-render-return-value'),
'react-in-jsx-scope': require('./lib/rules/react-in-jsx-scope'),
'jsx-uses-vars': require('./lib/rules/jsx-uses-vars'),
'jsx-handler-names': require('./lib/rules/jsx-handler-names'),
Expand Down Expand Up @@ -65,6 +66,7 @@ module.exports = {
'react/no-direct-mutation-state': 2,
'react/no-is-mounted': 2,
'react/no-unknown-property': 2,
'react/no-render-return-value': 2,
'react/prop-types': 2,
'react/react-in-jsx-scope': 2
}
Expand Down
62 changes: 62 additions & 0 deletions lib/rules/no-render-return-value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* @fileoverview Prevent usage of the return value of React.render
* @author Dustan Kasten
*/
'use strict';

var versionUtil = require('../util/version');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = function(context) {

// --------------------------------------------------------------------------
// Public
// --------------------------------------------------------------------------

return {

CallExpression: function(node) {
var callee = node.callee;
var parent = node.parent;
if (callee.type !== 'MemberExpression') {
return;
}

var calleeObjectName;
if (versionUtil.test(context, '15.0.0')) {
calleeObjectName = /^ReactDOM$/;
} else if (versionUtil.test(context, '0.14.0')) {
calleeObjectName = /^React(DOM)?$/;
} else if (versionUtil.test(context, '0.13.0')) {
calleeObjectName = /^React$/;
}

if (
callee.object.type !== 'Identifier' ||
!calleeObjectName.test(callee.object.name) ||
callee.property.name !== 'render'
) {
return;
}

if (
parent.type === 'VariableDeclarator' ||
parent.type === 'Property' ||
parent.type === 'ReturnStatement' ||
parent.type === 'ArrowFunctionExpression'
) {
context.report({
node: callee,
message: 'Do not depend on the return value from render'
});
}
}
};

};

module.exports.schema = [];

134 changes: 134 additions & 0 deletions tests/lib/rules/no-return-value-from-render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* @fileoverview Prevent usage of setState
* @author Mark Dalgleish
*/
'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

var rule = require('../../../lib/rules/no-render-return-value');
var RuleTester = require('eslint').RuleTester;

var parserOptions = {
ecmaVersion: 6,
ecmaFeatures: {
jsx: true
}
};

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

var ruleTester = new RuleTester();
ruleTester.run('no-render-return-value', rule, {

valid: [{
code: [
'ReactDOM.render(<div />, document.body);'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'let node;',
'ReactDOM.render(<div ref={ref => node = ref}/>, document.body);'
].join('\n'),
parserOptions: parserOptions
}, {
code: 'ReactDOM.render(<div ref={ref => this.node = ref}/>, document.body);',
parserOptions: parserOptions,
settings: {
react: {
version: '0.14.0'
}
}
}, {
code: 'React.render(<div ref={ref => this.node = ref}/>, document.body);',
parserOptions: parserOptions,
settings: {
react: {
version: '0.14.0'
}
}
}, {
code: 'React.render(<div ref={ref => this.node = ref}/>, document.body);',
parserOptions: parserOptions,
settings: {
react: {
version: '0.13.0'
}
}
}
],

invalid: [{
code: [
'var Hello = ReactDOM.render(<div />, document.body);'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Do not depend on the return value from render'
}]
}, {
code: [
'var o = {',
' inst: ReactDOM.render(<div />, document.body)',
'};'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Do not depend on the return value from render'
}]
}, {
code: [
'function render () {',
' return ReactDOM.render(<div />, document.body)',
'}'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Do not depend on the return value from render'
}]
}, {
code: 'var render = (a, b) => ReactDOM.render(a, b)',
parserOptions: parserOptions,
errors: [{
message: 'Do not depend on the return value from render'
}]
}, {
code: 'var inst = React.render(<div />, document.body);',
parserOptions: parserOptions,
settings: {
react: {
version: '0.14.0'
}
},
errors: [{
message: 'Do not depend on the return value from render'
}]
}, {
code: 'var inst = ReactDOM.render(<div />, document.body);',
parserOptions: parserOptions,
settings: {
react: {
version: '0.14.0'
}
},
errors: [{
message: 'Do not depend on the return value from render'
}]
}, {
code: 'var inst = React.render(<div />, document.body);',
parserOptions: parserOptions,
settings: {
react: {
version: '0.13.0'
}
},
errors: [{
message: 'Do not depend on the return value from render'
}]
}]
});

0 comments on commit 00c0d73

Please sign in to comment.