-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Coding Standards
Home > Knowledge Base > Coding Standards
- Testing and Documentation
-
Coding Standards
- Indentation
- Objects
- Strings
- Closure References to
this
-
Admin UI Front-end
- Syntax
- Order your methods with lifecycle first and render last
- Name handlers handleEventName
- Name handlers in props onEventName
- Open elements on the same line
- Align and sort HTML properties
- Only export a single react class - Language features
- Make "presentation" components pure
- Prefer props to state
- Use propTypes
- Never store state in the DOM
We are currently improving documentation and test coverage for Keystone, any help with this would be greatly appreciated.
Any additions or changes to functionality that has been documented should be accompanied by updates to the docs; these can be found in /docs/content/pages
. You can preview the http://keystonejs.com website locally by running node docs
from within the /docs
folder. Actual build and publishing of the website to the gh-pages
branch is managed by @JedWatson.
Before submitting a PR, please ensure the current test suite passes by running gulp test
.
Please see the editor and eslint settings for specific details:
Generally, you should follow these guidelines:
KeystoneJS uses tabs for indentation except in JSON, where 2 spaces should be used.
Reserved words should generally be avoided as object property keys, except where required by Mongoose (e.g. the default
option for Schema
paths).
Property keys should not be quoted unless they are invalid syntax; the same goes for using object notation to access properties. For example:
var obj = { x: 1 };
console.log(obj.x);
var obj = { 'some-property': 1 };
console.log(obj['some-property']);
Generally use single quotes. Double quotes may be used if it has a significantly positive impact on code readability (e.g. excessive escaping of single quotes required).
Strings longer than 80 characters should be written across multiple lines using string concatenation, unless using longer strings has a significantly positive impact on code readability.
Use .bind(this)
to avoid closure references to this
when it makes code more readable (small blocks).
When it's clearer to create a closure reference (e.g. larger blocks of code, or more than one level of binding required) use either self
or a descriptive variable name (e.g. field
) when self
could be misinterpreted.
Within your react component, you should order your methods like so:
- lifecycle methods (in chronological order):
staticMethod ()
constructor ()
componentWillMount ()
componentDidMount ()
componentWillReceiveProps ()
shouldComponentUpdate ()
componentWillUpdate ()
componentDidUpdate ()
componentWillUnmount ()
- everything else
render
Example:
<Component onClick={this.handleClick} onLaunchMissiles={this.handleLaunchMissiles} />
This is consistent with React's event naming: onClick
, onDrag
,
onChange
, etc.
Example:
<Component onLaunchMissiles={this.handleLaunchMissiles} />
Elements that span more than 80 characters or contain multiple nodes should open on a separate line.
Yes:
return (
<div>
<div>
...
</div>
</div>
);
Yes:
return <div>...</div>;
No:
return <div> // "div" is on the same line as "return"
<div>
...
</div>
</div>;
Fit them all on the same line if you can (80 characters). If you can't, put each property on a line of its own, indented, in sorted order. The closing angle brace should be on a line of its own, indented the same as the opening angle brace. This makes it easy to see the props at a glance.
Yes:
<div className="highlight" key="highlight-div">
<div
className="highlight"
key="highlight-div"
>
<Image
className="highlight"
key="highlight-div"
/>
No:
<div className="highlight" // property not on its own line
key="highlight-div"
>
<div // closing brace not on its own line
className="highlight"
key="highlight-div">
<div // property is not sorted
key="highlight-div"
className="highlight"
>
Every .jsx file should export a single react class, and nothing else. This is for testability: fixture frameworks requires it to function.
Note: The file can still define multiple classes, it just can't export more than one.
It's useful to think of the React world as divided into "logic" components and "presentation" components.
- "Logic" components have application logic, but do not emit HTML themselves.
- "Presentation" components are typically reusable, and do emit HTML.
Logic components can have internal state, but presentation components
never should. Prefer stateless functional components
unless a shouldComponentUpdate()
method is required.
Prefer props to state
You almost always want to use props. By avoiding state when possible, you minimize redundancy, making it easier to reason about your application.
A common pattern -- which matches the "logic" vs. "presentation" component distinction -- is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via props. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way.
Copying data from props to state can cause the UI to get out of sync and is especially bad.
Use propTypes
React Components should always have complete propTypes declared. Every attribute of this.props should have a corresponding entry in propTypes. This makes it easier for a developer unfamiliar with the component to understand it's scope and intention.
Avoid these non-descriptive prop-types:
React.PropTypes.any
React.PropTypes.array
React.PropTypes.object
Instead, use
React.PropTypes.arrayOf
React.PropTypes.objectOf
React.PropTypes.instanceOf
React.PropTypes.shape
Do not use data-
attributes or classes. All information
should be stored in Javascript.
Home | Copyright © 2016 Jed Watson