## **React Best Practices** - Lessons learned after a couple months of using React
These are some things I've found helpful after doing React for a couple months. It's possible these practices are short sighted and will cause other problems, I just haven't hit those bumps in the road yet.
This list started after reading this phenomincal article on [React Tips and Best Practicies](http://aeflash.com/2015-02/react-tips-and-best-practices.html).
#### 1. Always define your `propTypes`. Always.
Think of `propTypes` as a love letter to whatever developer will work on a component after you. Your components should be as declarative as possible. React's error messaging is so clear and helpful and this will make things so much easier.
#### 2. For any `propType` that isn't required, always set it in `getDefaultProps`
Defaults are not only helpful, this will reveals some code smells if you are passing around props that could be clarified further. If it isn't required and doesn't have a default what the hell is it?
#### 3. Rely on `...splats` over passing props explicity
Using splats (`{...this.props}`) when passing lots of props is so much less noisy. If your components `propTypes` are properly defined then there should be no mystery what it needs. Basically read the [Transferring Props](https://facebook.github.io/react/docs/transferring-props.html) documentation
##### A note on splats, destructuring assignment & coffeescript
Destructuring assignment of objects in coffeescript gets weird and the JSX compiling seems to miss this some times. There is also no `...` for objects. In place of that I've been using two patterns with `lodash`:
When your child components have a lot of props
```coffee
render: ->
moveStageProps = _.pick(@props, ['stage', 'searchStages', 'id'])
```
When your child components have a ton of props:
```coffee
render: ->
# Pull out the props into variables for the parent components
{ candidates, priorityOnly, groupBy, sortBy, parentName } = @props
# Omit those same props for the childComponents
childComponentProps = _.omit(@props, ['candidates','priorityOnly', 'groupBy', 'sortBy', 'parentName'])
```
#### 4. Place derived props or state in `render()` rather than in `getInitialState`
There are many times that you need to derive some sort of variable based on a prop or state. These values, if they can be deterministally set based on a specific prop or some aspect of the state should always be placed in the `render()` method
Bad:
```coffee
getInitialState: ->
vote: @props.cast_vote
priority_active: @props.cast_vote == 'priority'
```
Good:
```coffee
getInitialState: ->
vote: @props.cast_vote
render: ->
priority_active = @state.vote == 'priority'
```
#### 5. `React.addons.classSet` is limited and depricated. Make a `Classes()` method in `render()`
```coffee
popoverClasses = =>
classes = ['popover', 'bottom']
classes.push('is-visible') if @props.isPopoverVisible
classes.push("popover-#{type}")
classes.join(' ')
``
```