Skip to content

Commit 09a65af

Browse files
author
Roy Sutton
committed
Add new rule 'no-invalid-default-props'
Fixes jsx-eslint#1022
1 parent 8148833 commit 09a65af

File tree

4 files changed

+2269
-0
lines changed

4 files changed

+2269
-0
lines changed
+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Enforce all defaultProps have a corresponding non-required PropType (no-invalid-default-props)
2+
3+
This rule aims to ensure that any `defaultProp` has a non-required `PropType` declaration.
4+
5+
Having `defaultProps` for non-existent `propTypes` is likely the result of errors in refactoring
6+
or a sign of a missing `propType`. Having a `defaultProp` for a required property similarly
7+
indicates a possible refactoring problem.
8+
9+
## Rule Details
10+
11+
The following patterns are considered warnings:
12+
13+
```jsx
14+
function MyStatelessComponent({ foo, bar }) {
15+
return <div>{foo}{bar}</div>;
16+
}
17+
18+
MyStatelessComponent.propTypes = {
19+
foo: React.PropTypes.string.isRequired,
20+
bar: React.PropTypes.string
21+
};
22+
23+
MyStatelessComponent.defaultProps = {
24+
foo: "foo"
25+
};
26+
```
27+
28+
```jsx
29+
var Greeting = React.createClass({
30+
render: function() {
31+
return <div>Hello {this.props.foo} {this.props.bar}</div>;
32+
},
33+
34+
propTypes: {
35+
foo: React.PropTypes.string,
36+
bar: React.PropTypes.string
37+
},
38+
39+
getDefaultProps: function() {
40+
return {
41+
baz: "baz"
42+
};
43+
}
44+
});
45+
```
46+
47+
```jsx
48+
class Greeting extends React.Component {
49+
render() {
50+
return (
51+
<h1>Hello, {this.props.foo} {this.props.bar}</h1>
52+
);
53+
}
54+
}
55+
56+
Greeting.propTypes = {
57+
foo: React.PropTypes.string.isRequired,
58+
bar: React.PropTypes.string
59+
};
60+
61+
Greeting.defaultProps = {
62+
foo: "foo"
63+
};
64+
```
65+
66+
```jsx
67+
class Greeting extends React.Component {
68+
render() {
69+
return (
70+
<h1>Hello, {this.props.foo} {this.props.bar}</h1>
71+
);
72+
}
73+
74+
static propTypes = {
75+
foo: React.PropTypes.string,
76+
bar: React.PropTypes.string.isRequired
77+
};
78+
79+
static defaultProps = {
80+
baz: "baz"
81+
};
82+
}
83+
```
84+
85+
```jsx
86+
type Props = {
87+
foo: string,
88+
bar?: string
89+
};
90+
91+
function MyStatelessComponent(props: Props) {
92+
return <div>Hello {props.foo} {props.bar}</div>;
93+
}
94+
95+
MyStatelessComponent.defaultProps = {
96+
foo: "foo",
97+
bar: "bar"
98+
}
99+
```
100+
101+
The following patterns are not considered warnings:
102+
103+
```jsx
104+
function MyStatelessComponent({ foo, bar }) {
105+
return <div>{foo}{bar}</div>;
106+
}
107+
108+
MyStatelessComponent.propTypes = {
109+
foo: React.PropTypes.string,
110+
bar: React.PropTypes.string.isRequired
111+
};
112+
```
113+
114+
```jsx
115+
function MyStatelessComponent({ foo, bar }) {
116+
return <div>{foo}{bar}</div>;
117+
}
118+
119+
MyStatelessComponent.propTypes = {
120+
foo: React.PropTypes.string.isRequired,
121+
bar: React.PropTypes.string
122+
};
123+
124+
MyStatelessComponent.defaultProps = {
125+
bar: 'some default'
126+
};
127+
```
128+
129+
```jsx
130+
type Props = {
131+
foo: string,
132+
bar?: string
133+
};
134+
135+
function MyStatelessComponent(props: Props) {
136+
return <div>Hello {props.foo} {props.bar}</div>;
137+
}
138+
139+
MyStatelessComponent.defaultProps = {
140+
bar: 'some default'
141+
};
142+
```
143+
144+
```js
145+
function NotAComponent({ foo, bar }) {}
146+
147+
NotAComponent.propTypes = {
148+
foo: React.PropTypes.string,
149+
bar: React.PropTypes.string.isRequired
150+
};
151+
```
152+
153+
## Rule Options
154+
155+
```js
156+
...
157+
"no-invalid-default-props": [<enabled>, { "allowRequiredDefaults": <boolean> }]
158+
...
159+
```
160+
161+
### `allowRequiredDefaults`
162+
163+
When `true` the rule will ignore `defaultProps` for `isRequired` `propTypes`.
164+
165+
The following patterns are considered okay and do not cause warnings:
166+
167+
```jsx
168+
function MyStatelessComponent({ foo, bar }) {
169+
return <div>{foo}{bar}</div>;
170+
}
171+
172+
MyStatelessComponent.propTypes = {
173+
foo: React.PropTypes.string.isRequired,
174+
bar: React.PropTypes.string
175+
};
176+
177+
MyStatelessComponent.defaultProps = {
178+
foo: "foo"
179+
};
180+
```
181+
182+
## When Not To Use It
183+
184+
If you don't care about stray `defaultsProps` in your components, you can disable this rule.
185+
186+
## Related rules
187+
188+
- [require-default-props](./require-default-props.md)
189+
190+
# Resources
191+
- [Official React documentation on defaultProps](https://facebook.github.io/react/docs/typechecking-with-proptypes.html#default-prop-values)
192+

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var allRules = {
2727
'jsx-no-bind': require('./lib/rules/jsx-no-bind'),
2828
'jsx-no-undef': require('./lib/rules/jsx-no-undef'),
2929
'no-unknown-property': require('./lib/rules/no-unknown-property'),
30+
'no-invalid-default-props': require('./lib/rules/no-invalid-default-props'),
3031
'jsx-curly-spacing': require('./lib/rules/jsx-curly-spacing'),
3132
'jsx-equals-spacing': require('./lib/rules/jsx-equals-spacing'),
3233
'jsx-sort-props': require('./lib/rules/jsx-sort-props'),

0 commit comments

Comments
 (0)