init source
This commit is contained in:
+97
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @fileoverview Prevent usage of setState in lifecycle methods
|
||||
* @author Yannick Croissant
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const docsUrl = require('./docsUrl');
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
function mapTitle(methodName) {
|
||||
const map = {
|
||||
componentDidMount: 'did-mount',
|
||||
componentDidUpdate: 'did-update',
|
||||
componentWillUpdate: 'will-update'
|
||||
};
|
||||
const title = map[methodName];
|
||||
if (!title) {
|
||||
throw Error(`No docsUrl for '${methodName}'`);
|
||||
}
|
||||
return `no-${title}-set-state`;
|
||||
}
|
||||
|
||||
function makeNoMethodSetStateRule(methodName, shouldCheckUnsafeCb) {
|
||||
return {
|
||||
meta: {
|
||||
docs: {
|
||||
description: `Prevent usage of setState in ${methodName}`,
|
||||
category: 'Best Practices',
|
||||
recommended: false,
|
||||
url: docsUrl(mapTitle(methodName))
|
||||
},
|
||||
|
||||
schema: [{
|
||||
enum: ['disallow-in-func']
|
||||
}]
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const mode = context.options[0] || 'allow-in-func';
|
||||
|
||||
function nameMatches(name) {
|
||||
if (name === methodName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof shouldCheckUnsafeCb === 'function' && shouldCheckUnsafeCb(context)) {
|
||||
return name === `UNSAFE_${methodName}`;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Public
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
|
||||
CallExpression(node) {
|
||||
const callee = node.callee;
|
||||
if (
|
||||
callee.type !== 'MemberExpression' ||
|
||||
callee.object.type !== 'ThisExpression' ||
|
||||
callee.property.name !== 'setState'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const ancestors = context.getAncestors(callee).reverse();
|
||||
let depth = 0;
|
||||
ancestors.some((ancestor) => {
|
||||
if (/Function(Expression|Declaration)$/.test(ancestor.type)) {
|
||||
depth++;
|
||||
}
|
||||
if (
|
||||
(ancestor.type !== 'Property' && ancestor.type !== 'MethodDefinition' && ancestor.type !== 'ClassProperty') ||
|
||||
!nameMatches(ancestor.key.name) ||
|
||||
(mode !== 'disallow-in-func' && depth > 1)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
context.report({
|
||||
node: callee,
|
||||
message: `Do not use setState in ${ancestor.key.name}`
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = makeNoMethodSetStateRule;
|
||||
Reference in New Issue
Block a user