no-children-prop.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. messages: {
  35. nestChildren: 'Do not pass children as props. Instead, nest children between the opening and closing tags.',
  36. passChildrenAsArgs: 'Do not pass children as props. Instead, pass them as additional arguments to React.createElement.'
  37. },
  38. schema: []
  39. },
  40. create(context) {
  41. return {
  42. JSXAttribute(node) {
  43. if (node.name.name !== 'children') {
  44. return;
  45. }
  46. context.report({
  47. node,
  48. messageId: 'nestChildren'
  49. });
  50. },
  51. CallExpression(node) {
  52. if (!isCreateElementWithProps(node)) {
  53. return;
  54. }
  55. const props = node.arguments[1].properties;
  56. const childrenProp = props.find((prop) => prop.key && prop.key.name === 'children');
  57. if (childrenProp) {
  58. context.report({
  59. node,
  60. messageId: 'passChildrenAsArgs'
  61. });
  62. }
  63. }
  64. };
  65. }
  66. };