React Component - Tuong-Nguyen/JavaScript-Structure GitHub Wiki

Create component

Use React.createClass()

const SkiDayCount = React.createClass({ })

Methods are separated by commas

Use ES6 class

class SkiDayCount extends React.Component {}

Methods are defined as functions

No autobind

Component is created by ES6 has no autobind. If we want to bind a event handler, we must call manually bind() method in constructor. ES5:

<input type="button" onClick={this.handleClick} />

ES6:

constructor(props) {
  super(props);
  this.handleClick = this.handleClick.bind(this)
}
<input type="button" onClick={this.handleClick} />

Stateless functional component

React Stateless component

Props

Watch in Browser console $r is "this" in component, for example, to get props of component, we use $r.props

Define prop in component tag

render(<SkiDayCount total={50} powder={20} backcountry={10} goal={100} />
  , document.getElementById('root'));
  • Get prop value. In component render() method
this.props.total

Default Props

Use defaultProps

SkiDayCount.defaultProps = {
  total: 50,
  powder:10,
  backcountry:15,
  goal:100
};

Use ES6 default value

export const SkiDayCount = ({total=50, powder=10, backcountry=15, goal=100}) => ()

Validating with React.PropTypes

Import

import {PropTypes} from 'react';

Usage

SkiDayCount.propTypes = {
  total: PropTypes.number,
  powder: PropTypes.number,
  backcountry: PropTypes.number,
  goal: PropTypes.number.isRequired
}
  • PropTypes.number: the property must be a number
  • PropTypes.isRequired: the property must be required
  • More PropTypes

If the property is invalid, there is warning in browser's console.

Custom validation

  • The validation is a function
  • If the property is invalid, it returns an error by new Error(), otherwise, it returns null
SkiDayList.propTypes = {
  days: function(props) {
    if (!Array.isArray(props.days)) {
      return new Error(
        "SkiDayList should be an array"
      );
    } else if (!props.days.length) {
      return new Error(
        "SkiDayList must have at least one record"
      );
    } else {
      return null;
    }
  }
}

State

State with React.createClass()

  • Override getInitialState(), return state
getInitialState() {
  return {
     allSkiDays: [
            {
              resort: "SquaW Valley",
              date: new Date('6/1/2017'),
              powder: true,
              backcountry: false
            }
            // ...
     ]
  }
}
  • Get
this.state.allSkiDays

State with ES6 class

Set state in the constructor

export class App extends Component{
  constructor(props) {
    super(props);
    this.state = {
      allSkiDays: [
        {
          resort: "SquaW Valley",
          date: new Date('6/1/2017'),
          powder: true,
          backcountry: false
        }
        // ...
      ]
    };
  }

Load data list to component

  • SkiDayRow component
export const SkiDayRow = ({resort, date, powder, backcountry}) => (
    <tr>
      <td>{date.getDate()}/{date.getMonth()+1}/{date.getFullYear()}</td>
      <td>{resort}</td>
      <td>{powder ? <SnowFlake/> : null}</td>
      <td>{backcountry ? <Terrain/> : null}</td>
    </tr>
);
  • Use map((<item>, <index>) => ...) to go through each item
 {days.map((day, i) => <SkiDayRow key={i}
                                     resort={day.resort}
                                     date={day.date}
                                     powder={day.powder}
                                     backcountry={day.backcountry}
    />)}
  • Every child component rendering from an array must has a key so that React knows what to update
⚠️ **GitHub.com Fallback** ⚠️