Last active
June 18, 2018 13:48
-
-
Save UdaraJay/853cf8657c0d8878a1a65f7334950dbb to your computer and use it in GitHub Desktop.
Sample class based react component - ES6 (Best practices)
This file contains 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
// Using this as a way to collect my 'best-practices' for React | |
// The structure of a good class based component | |
import React, { Component } from 'react' | |
// MobX is designed to enable building web applications with a complex data model in an intuitive and very performant manner. | |
import { observer } from 'mobx-react' | |
// A runtime checker for props | |
import { string, object } from 'prop-types' | |
// Import your styles from its own file to keep things neat | |
import '.styles/SampleContainer.css' | |
// Binding the mobx observer to the component | |
@observer | |
export default class SampleContainer extends Component { | |
// Good to define your states here, makes it easier for others to read | |
state = { expanded : false } | |
// Used by the checker, setup your props before assigning defaults | |
static propTypes = { | |
model: object.isRequired, | |
title: string | |
} | |
static defaultProps = { | |
model: { | |
id: 0 | |
}, | |
title: 'Your pretty name' | |
} | |
// The ES6 arrow functions bind the function to the right component (when passing down to a sub-component) | |
// So you don't have to do this.handleSubmit.bind(this) all the time | |
handleSubmit = (e) => { | |
e.preventDefault() | |
this.props.model.save() | |
} | |
handleNameChange = (e) => { | |
// Passing in the target... nothing special; just works because of the the arrow functions | |
this.props.model.changeName(e.target.value) | |
} | |
handleExpanded =(e) => { | |
e.preventDefault() | |
// Interesting learning here... | |
// set state is asynchronous so... if you were to set your state like this: | |
// this.setState({ expanded: !this.state.expanded }) | |
// You can't really be sure what the state is (because it's asynchronous!) | |
// Here you're passing a function to setState with the previous state as an argument | |
this.setState(prevState => ({ expanded: !prevState.expanded })) | |
} | |
render() { | |
const{ | |
model, | |
title | |
} = this.props | |
return ( | |
<SubComponent | |
onSubmit={this.handleSubmit} | |
onNameChange-{this.handleNameChange} | |
onExpanded={this.handleExpanded}> | |
<div> | |
<h1>{title}</h1> | |
<input | |
type='text' | |
value={model.name} | |
// Always pass closures like below, you don't want functions being re-created | |
// each time the component is rendered -- avoid unnecessary overhead | |
onChange={this.handleNameChange} | |
placeholder='Your name' /> | |
</div> | |
</SubComponent> | |
) | |
} | |
} | |
// Credits: https://engineering.musefind.com/our-best-practices-for-writing-react-components-dec3eb5c3fc8 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment