no-children-prop.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /**
  2. * @fileoverview Prevent passing of children as props
  3. * @author Benjamin Stepp
  4. */
  5. 'use strict';
  6. const docsUrl = require('../util/docsUrl');
  7. // ------------------------------------------------------------------------------
  8. // Helpers
  9. // ------------------------------------------------------------------------------
  10. /**
  11. * Checks if the node is a createElement call with a props literal.
  12. * @param {ASTNode} node - The AST node being checked.
  13. * @returns {Boolean} - True if node is a createElement call with a props
  14. * object literal, False if not.
  15. */
  16. function isCreateElementWithProps(node) {
  17. return node.callee
  18. && node.callee.type === 'MemberExpression'
  19. && node.callee.property.name === 'createElement'
  20. && node.arguments.length > 1
  21. && node.arguments[1].type === 'ObjectExpression';
  22. }
  23. // ------------------------------------------------------------------------------
  24. // Rule Definition
  25. // ------------------------------------------------------------------------------
  26. module.exports = {
  27. meta: {
  28. docs: {
  29. description: 'Prevent passing of children as props.',
  30. category: 'Best Practices',
  31. recommended: true,
  32. url: docsUrl('no-children-prop')
  33. },
  34. schema: []
  35. },
  36. create: function(context) {
  37. return {
  38. JSXAttribute: function(node) {
  39. if (node.name.name !== 'children') {
  40. return;
  41. }
  42. context.report({
  43. node: node,
  44. message: 'Do not pass children as props. Instead, nest children between the opening and closing tags.'
  45. });
  46. },
  47. CallExpression: function(node) {
  48. if (!isCreateElementWithProps(node)) {
  49. return;
  50. }
  51. const props = node.arguments[1].properties;
  52. const childrenProp = props.find(prop => prop.key && prop.key.name === 'children');
  53. if (childrenProp) {
  54. context.report({
  55. node: node,
  56. message: 'Do not pass children as props. Instead, pass them as additional arguments to React.createElement.'
  57. });
  58. }
  59. }
  60. };
  61. }
  62. };