Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

85 строки
2.3 KiB

  1. /**
  2. * @fileoverview Prevent usage of setState in lifecycle methods
  3. * @author Yannick Croissant
  4. */
  5. 'use strict';
  6. const docsUrl = require('./docsUrl');
  7. // ------------------------------------------------------------------------------
  8. // Rule Definition
  9. // ------------------------------------------------------------------------------
  10. function makeNoMethodSetStateRule(methodName, shouldCheckUnsafeCb) {
  11. return {
  12. meta: {
  13. docs: {
  14. description: `Prevent usage of setState in ${methodName}`,
  15. category: 'Best Practices',
  16. recommended: false,
  17. url: docsUrl(methodName)
  18. },
  19. schema: [{
  20. enum: ['disallow-in-func']
  21. }]
  22. },
  23. create: function(context) {
  24. const mode = context.options[0] || 'allow-in-func';
  25. function nameMatches(name) {
  26. if (name === methodName) {
  27. return true;
  28. }
  29. if (typeof shouldCheckUnsafeCb === 'function' && shouldCheckUnsafeCb(context)) {
  30. return name === `UNSAFE_${methodName}`;
  31. }
  32. return false;
  33. }
  34. // --------------------------------------------------------------------------
  35. // Public
  36. // --------------------------------------------------------------------------
  37. return {
  38. CallExpression: function(node) {
  39. const callee = node.callee;
  40. if (
  41. callee.type !== 'MemberExpression' ||
  42. callee.object.type !== 'ThisExpression' ||
  43. callee.property.name !== 'setState'
  44. ) {
  45. return;
  46. }
  47. const ancestors = context.getAncestors(callee).reverse();
  48. let depth = 0;
  49. for (let i = 0, j = ancestors.length; i < j; i++) {
  50. const ancestor = ancestors[i];
  51. if (/Function(Expression|Declaration)$/.test(ancestor.type)) {
  52. depth++;
  53. }
  54. if (
  55. (ancestor.type !== 'Property' && ancestor.type !== 'MethodDefinition') ||
  56. !nameMatches(ancestor.key.name) ||
  57. (mode !== 'disallow-in-func' && depth > 1)
  58. ) {
  59. continue;
  60. }
  61. context.report({
  62. node: callee,
  63. message: `Do not use setState in ${ancestor.key.name}`
  64. });
  65. break;
  66. }
  67. }
  68. };
  69. }
  70. };
  71. }
  72. module.exports = makeNoMethodSetStateRule;