Web interface using React (2)

ECA Node/React - June 2019

Last time

  • Parcel, Babel, jsx...
  • Quick intro to some React concepts
  • Our first component

Today

  • Introduction to state and props
  • How to handle events
  • Some style with Bulma
  • Practice

Quick modification to the package json

  "dependencies": {
    "@babel/runtime": "^7.5.1",
    "babel-polyfill": "^6.26.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6"
  },
  "devDependencies": {
    "@babel/core": "^7.5.0",
    "@babel/plugin-transform-runtime": "^7.4.4",
    "@babel/preset-env": "^7.5.0",
    "@babel/preset-react": "^7.0.0",
    "babel-eslint": "^10.0.2",
    "eslint": "^5.16.0",
    "eslint-config-prettier": "^4.3.0",
    "eslint-config-prettier-standard": "^2.0.0",
    "eslint-config-standard": "^12.0.0",
    "eslint-config-standard-react": "^7.0.2",
    "eslint-plugin-import": "^2.17.3",
    "eslint-plugin-jest": "^22.6.4",
    "eslint-plugin-node": "^9.1.0",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-promise": "^4.1.1",
    "eslint-plugin-react": "^7.13.0",
    "eslint-plugin-standard": "^4.0.0",
    "parcel-bundler": "^1.12.3",
    "prettier": "1.17.1"
  }

package.json

Rendering lists

import React, { Component } from 'react'

class List extends Component {
  constructor() {
    super()
    this.state = {
      services: [{ service_name: 'checkout-service', service_version: '2019-07-01-07-31-fa2a5bf93',},
        //...,
      ],
    }
  }
  render() {
    return (
      <div>
        <table>
          <thead>
            <tr>
              <th>Service name</th>
              <th>Service version</th>
            </tr>
          </thead>
          <tbody>
            {this.state.services.map(service => (
              <tr>
                <td>{service.service_name}</td>
                <td>{service.service_version}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    )
  }
}

export default List
import React, { Component } from 'react'

class Row extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <tr>
        <td>{this.props.service.service_name}</td>
        <td>{this.props.service.service_version}</td>
      </tr>
    )
  }
}
export default Row
//[...]
{this.state.services.map(service => (
  <Row service={service} />
))}

src/components/Row.jsx

src/components/List.jsx

import React from 'react'

const Row = ({ service: { service_name, service_version } }) => (
  <tr>
    <td>{service_name}</td>
    <td>{service_version}</td>
  </tr>
)

export default Row
import React from 'react'

const Row = (props) => (
  <tr>
    <td>{props.service.service_name}</td>
    <td>{props.service.service_version}</td>
  </tr>
)

export default Row

How to handle events

import React, { Component } from 'react'
import Row from './Row'

class List extends Component {
  constructor() {
    super()
    this.state = {
      inputValue: '',
      // ...
  }
  filterServices(inputValue) {
    this.setState({
      inputValue,
    })
  }
  render() {
    return (
      <div>
        <input
          type='text'
          placeholder='Filter'
          onChange={event => this.filterServices(event.target.value)}
        />
        <table>
          // ...
          <tbody>
            {this.state.services
              .filter(
                service =>
                  service.service_name.indexOf(this.state.inputValue) >= 0,
              )
              .map(service => (
                <Row key={service.service_name} service={service} />
              ))}
          </tbody>
        </table>
      </div>
    )
  }
}

export default List

What happens when state changes?

State

  • Local to the component
  • Other components cannot access it
  • Some components do not need a state object

Props

  • Passed to a component
  • Once passed to the component, it cannot be modified

VS

Add some style

<span 
    className='custom-title' 
    style={{ fontSize: 20 }}
>Hello</span>

Bulma

npm i bulma

Practice

Create a component that can add a dummy service

import React, { Component } from 'react'

class AddService extends Component {
  render() {
    return (
      <div className='field is-grouped'>
        <div className='control is-expanded'>
          <input
            className='input'
            type='text'
            placeholder='Add a new service'
          />
        </div>
        <div className='control'>
          <button
            className='button is-primary'
          >
            Add
          </button>
        </div>
      </div>
    )
  }
}

export default AddService

src/components/AddService.jsx

Made with Slides.com