Skip to content

Commit f1ca75d

Browse files
committed
Fix props validation for nested stateless components (fixes #331)
1 parent bccf86b commit f1ca75d

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

lib/rules/prop-types.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,23 @@ module.exports = Components.detect(function(context, components, utils) {
153153

154154
/**
155155
* Checks if the prop is declared
156-
* @param {Object} component The component to process
156+
* @param {ASTNode} node The AST node being checked.
157157
* @param {String[]} names List of names of the prop to check.
158158
* @returns {Boolean} True if the prop is declared, false if not.
159159
*/
160-
function isDeclaredInComponent(component, names) {
161-
return _isDeclaredInComponent(
162-
component.declaredPropTypes || {},
163-
names
164-
);
160+
function isDeclaredInComponent(node, names) {
161+
while (node) {
162+
var component = components.get(node);
163+
var isDeclared =
164+
component && component.confidence === 2 &&
165+
_isDeclaredInComponent(component.declaredPropTypes || {}, names)
166+
;
167+
if (isDeclared) {
168+
return true;
169+
}
170+
node = node.parent;
171+
}
172+
return false;
165173
}
166174

167175
/**
@@ -532,7 +540,7 @@ module.exports = Components.detect(function(context, components, utils) {
532540
allNames = component.usedPropTypes[i].allNames;
533541
if (
534542
isIgnored(allNames[0]) ||
535-
isDeclaredInComponent(component, allNames)
543+
isDeclaredInComponent(component.node, allNames)
536544
) {
537545
continue;
538546
}

tests/lib/rules/prop-types.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,24 @@ ruleTester.run('prop-types', rule, {
935935
jsx: true,
936936
experimentalObjectRestSpread: true
937937
}
938+
}, {
939+
code: [
940+
'const statelessComponent = (props) => {',
941+
' const subRender = () => {',
942+
' return <span>{props.someProp}</span>;',
943+
' };',
944+
' return <div>{subRender()}</div>;',
945+
'};',
946+
'statelessComponent.propTypes = {',
947+
' someProp: PropTypes.string',
948+
'};'
949+
].join('\n'),
950+
env: {
951+
es6: true
952+
},
953+
ecmaFeatures: {
954+
jsx: true
955+
}
938956
}
939957
],
940958

0 commit comments

Comments
 (0)