-
-
Save vuquangtam/5d6e5a9ee700a9f8959a996759d2b201 to your computer and use it in GitHub Desktop.
React Best Practices - Lessons learned after a couple months of using React
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. | |
| ## 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']) | |
| <MoveStage {...moveStageProps} /> | |
| ``` | |
| 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 `<component>Classes()` method `in render()` | |
| ```coffee | |
| popoverClasses = => | |
| classes = ['popover', 'bottom'] | |
| classes.push('is-visible') if @props.isPopoverVisible | |
| classes.push("popover-#{type}") | |
| classes.join(' ') | |
| `<div className={popoverClasses()} >` | |
| ``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment