Skip to content

Commit 6c4accd

Browse files
committed
Merge pull request #78 from yannickcr/rule-sort-comp
Add sort-comp rule (fixes #39)
2 parents 33a8be0 + 8b93659 commit 6c4accd

File tree

5 files changed

+770
-2
lines changed

5 files changed

+770
-2
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Finally, enable all of the rules that you would like to use.
5757
"react/prop-types": 1,
5858
"react/react-in-jsx-scope": 1,
5959
"react/self-closing-comp": 1,
60+
"react/sort-comp": 1,
6061
"react/wrap-multilines": 1
6162
}
6263
}
@@ -79,6 +80,7 @@ Finally, enable all of the rules that you would like to use.
7980
* [prop-types](docs/rules/prop-types.md): Prevent missing props validation in a React component definition
8081
* [react-in-jsx-scope](docs/rules/react-in-jsx-scope.md): Prevent missing React when using JSX
8182
* [self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children
83+
* [sort-comp](docs/rules/sort-comp.md): Enforce component methods order
8284
* [wrap-multilines](docs/rules/wrap-multilines.md): Prevent missing parentheses around multilines JSX
8385

8486
## To Do

docs/rules/sort-comp.md

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Enforce component methods order (sort-comp)
2+
3+
When creating React components it is more convenient to always follow the same organisation for methods order to helps you to easily find lifecyle methods, event handlers, etc.
4+
5+
## Rule Details
6+
7+
With default configuration the following organisation must be followed:
8+
9+
1. lifecycle methods: `displayName` ,`propTypes` ,`mixins` ,`statics` ,`getDefaultProps` ,`getInitialState` ,`componentWillMount` ,`componentDidMount` ,`componentWillReceiveProps` ,`shouldComponentUpdate` ,`componentWillUpdate` ,`componentDidUpdate` ,`componentWillUnmount` (in this order).
10+
2. custom methods
11+
3. `render` method
12+
13+
The following patterns are considered warnings:
14+
15+
```js
16+
var Hello = React.createClass({
17+
render: function() {
18+
return <div>Hello</div>;
19+
},
20+
displayName : 'Hello'
21+
});
22+
```
23+
24+
The following patterns are not considered warnings:
25+
26+
```js
27+
var Hello = React.createClass({
28+
displayName : 'Hello',
29+
render: function() {
30+
return <div>Hello</div>;
31+
}
32+
});
33+
```
34+
35+
## Rule Options
36+
37+
This rule can take one argument to customize the components organisation.
38+
39+
```
40+
...
41+
"react/sort-comp": [<enabled>, { order: <order>, groups: <groups> }]
42+
...
43+
```
44+
45+
* `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.
46+
* `order`: optional array of methods to validate.
47+
* `groups`: optional object of methods groups.
48+
49+
The default configuration is:
50+
51+
```js
52+
{
53+
order: [
54+
'lifecycle',
55+
'everything-else',
56+
'render'
57+
],
58+
groups: {
59+
lifecycle: [
60+
'displayName',
61+
'propTypes',
62+
'mixins',
63+
'statics',
64+
'getDefaultProps',
65+
'getInitialState',
66+
'componentWillMount',
67+
'componentDidMount',
68+
'componentWillReceiveProps',
69+
'shouldComponentUpdate',
70+
'componentWillUpdate',
71+
'componentDidUpdate',
72+
'componentWillUnmount'
73+
]
74+
}
75+
}
76+
```
77+
78+
* `lifecycle` is refering to the `lifecycle` group defined in `groups`.
79+
* `everything-else` is a special group that match all the methods that do not match any of the other groups.
80+
* `render` is refering to the `render` method.
81+
82+
You can override this configuration to match your needs.
83+
84+
For example, if you want to place your event handlers (`onClick`, `onSubmit`, etc.) before `render` but the other methods after it:
85+
86+
```js
87+
"react/sort-comp": [1, {
88+
order: [
89+
'lifecycle',
90+
'/^on.+$/',
91+
'render',
92+
'everything-else'
93+
]
94+
}]
95+
```
96+
97+
With the above configuration, the following patterns are considered warnings:
98+
99+
```js
100+
var Hello = React.createClass({
101+
render: function() {
102+
return <div>Hello</div>;
103+
},
104+
onClick: function() {}
105+
});
106+
```
107+
108+
With the above configuration, the following patterns are not considered warnings:
109+
110+
```js
111+
var Hello = React.createClass({
112+
onClick: function() {},
113+
render: function() {
114+
return <div>Hello</div>;
115+
}
116+
});
117+
```
118+
119+
If you want to split your `render` method into smaller ones and keep them just before render:
120+
121+
```js
122+
"react/sort-comp": [1, {
123+
order: [
124+
'lifecycle',
125+
'everything-else',
126+
'rendering',
127+
],
128+
groups: {
129+
rendering: [
130+
'/^render.+$/',
131+
'render'
132+
]
133+
}
134+
}]
135+
```
136+
137+
With the above configuration, the following patterns are considered warnings:
138+
139+
```js
140+
var Hello = React.createClass({
141+
renderButton: function() {},
142+
onClick: function() {},
143+
render: function() {
144+
return <div>Hello</div>;
145+
}
146+
});
147+
```
148+
149+
With the above configuration, the following patterns are not considered warnings:
150+
151+
```js
152+
var Hello = React.createClass({
153+
onClick: function() {},
154+
renderButton: function() {},
155+
render: function() {
156+
return <div>Hello</div>;
157+
}
158+
});
159+
```
160+
161+
## When Not To Use It
162+
163+
This rule is a formatting preference and not following it won't negatively affect the quality of your code. If components organisation isn't a part of your coding standards, then you can leave this rule off.

index.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ module.exports = {
1717
'no-unknown-property': require('./lib/rules/no-unknown-property'),
1818
'jsx-sort-props': require('./lib/rules/jsx-sort-props'),
1919
'jsx-sort-prop-types': require('./lib/rules/jsx-sort-prop-types'),
20-
'jsx-boolean-value': require('./lib/rules/jsx-boolean-value')
20+
'jsx-boolean-value': require('./lib/rules/jsx-boolean-value'),
21+
'sort-comp': require('./lib/rules/sort-comp')
2122
},
2223
rulesConfig: {
2324
'jsx-uses-react': 0,
@@ -35,6 +36,7 @@ module.exports = {
3536
'no-unknown-property': 0,
3637
'jsx-sort-props': 0,
3738
'jsx-sort-prop-types': 0,
38-
'jsx-boolean-value': 0
39+
'jsx-boolean-value': 0,
40+
'sort-comp': 0
3941
}
4042
};

0 commit comments

Comments
 (0)