Skip to content

Understanding React

Songkeys edited this page Mar 12, 2019 · 2 revisions

React coding

Intro

Our code is not that advanced in terms of react coding. So once you understand react you will be able to understand what each part does.

React coding is basically about creating custom html tags (called components), however these tags are written in JavaScript (as is all parts of a react app). Then the JavaScript is converted into html tags and injected into a html document (which usually contains nothing but a root <div> in the <body>).

Each component has a return () which contains the output html you want to display.

return(
  <p>
    Hello World
  </p>
)

The components can be created as classes (part of ES6, a version of JavaScript, I think) or as just functions.

Classes

Classes are for 'stateful' components, meaning they have data they need to keep track of and need multiple functions.

They require you to encapsulate the return () inside a render () {} method.

export default class Dashboard extends Component {
  render () {
    return(
      <p>
        Hello World
      </p>
    )
  }
}

...extends Component

They always have to extend Component which is a React class that needs to be imported. import { Component } from 'react'

However every react component needs to also import React from 'react' so they are often combined into one statement. import React, { Component } from 'react'

p.s. the import statements, like other languages, are usually at the top.


export default ...

This exports the component so that it can be used in other components. Much the same as Classes/Objects in Java are used in other Objects.

Functions

Function implementation is for 'stateless' components, meaning they are pretty basic... usually just taking in some data (get onto this later using props) and displaying it in its return() html.

function RatingPerDay(props) { //ignore props for now
  return (
    <p>
      Hello World
    </p>
  )
}

export default RatingPerDay // still need to export function components - note exports can be done in this way with class components (at end of file) (just preference).

note there is no render () {} wrapper method (because functions can't have functions within them and naturally have a return so the render isn't necessary).

Life Cycle Methods

(only for classes, as functions can't contain methods like we discussed already).

Life Cycle methods are predefined methods for components in react which are automatically called on specific actions. For example:

constructor(props) { //ignore props for now - just used to pass in  
  super(props)
  ...
}

constructor() {} is called when a class component is made. super(props) is called because in ES6 super() must be called in the constructor of all sub classes!

and

componentDidMount() {
    this.getData() // This just calls a method named get data. Can ignore.
  }

componentDidMount() {} is called when the component successfully 'mounts' (is injected into the html, I think), thus it can be used to pre-load data from the back-end before the html is displayed.

State

State is obviously only considered in stateful components, so only class components.

this.state is a variable that is used to hold any data that the class needs to remember/hold. It holds a JavaScript Object, which is similar to JSON.

{
  key: value,
  key2: value
}

Initialising the state

For example we might hold a message variable there:

export default class Dashboard extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: "Hello World" 
    }
  }

We can use the constructor to set the default values of the state (I think there is another way with just doing state = {} directly in the class).


Updating the state

To update a state variable we use:

this.setState({
  message: "Goodbye Universe"
})

Note: this will NOT change any other state variables (they will stay as they are).


Accessing a state variable

const message = this.state.message

Note: the const is used in JavaScript to make a variable immutable (cannot be changed).

Using state and varaibles in the return() html

One of the most powerful things about react is the ability to easily inject data into any part of a components html.

...
render() {
    return (
      <p>
        {this.state.message}
      </p>
    )
  }

{ } can be used in the return to inject any variables that are in your class (usually the state variables, as you want to display changes to these to the html in some way. e.g. changing what the message says). Another example would be to use this to display the props in a similar way.

Embedded components

Components can be used in other components, similar to Objects in Java.

  1. First the component must be imported into the file you want to use it in.

import RatingPerDay from './components/RatingPerDay/RatingPerDay'

...'./components/RatingPerDay/RatingPerDay' is the file path to the components file.

  1. Next the Component can be used in the return() of the component you are in.
render() {
    return (
      <RatingPerDay />
    )
  }

this would return/display a RatingPerDay component. Works like function calls, trying to display a RatingPerDay means you first have to find what a RatingPerDay component looks like? This is what it returns in its return().

Props

Finally props!

props are the properties/attributes passed into the component from its parent (the one that imports and displays it). used to pass data to a child component.


Passing props to a child component

props are passed the same way attributes are passed to a html tag.

<div style={...}>
<RatingPerDay data={"Hello World"} data2={2} fizz={3}>

this would pass 3 props to the child component. Props are received in side the prop object similar to the state object.

**this.props**.data + **this.props**.data2 + **this.props**.fizz hopefully you can see the format for accessing props :D

stealing our last example:

render() {
    return (
      <RatingPerDay data={this.state.negativePerDay}/> //passes this.state.negativePerDay -> props.data
    )
  }

Accessing props in the child

function RatingPerDay(**props**) {
  const data = **props.data**.map(el => ({
    date: moment(el.date).format('YYYY/MM/DD'),
    volume: el.volume,
  })) // see the **use of this.props** to access the **data prop** that was passed in - can ignore the other stuff.
}

export default RatingPerDay

PropTypes

defining prop types is not necessary, but it is good practice as you can specify what data type each prop should except and whether each prop isRequired or not.

  1. First need to import a react library which holds the prop types.

import PropTypes from 'prop-types'

  1. Next we can define the prop-types for a component.
function RatingPerDay(props) {
  ...
}

RatingPerDay.propTypes = {
  data: PropTypes.arrayOf(PropTypes.object).isRequired, // each prop should be defined.
}

Different example:

**export default** function FeedbackAvgRating(props) {
  FeedbackAvgRating.propTypes = {
    avgrating: PropTypes.number.isRequired,
  }
  ...
}

Note in the second example the export default is done in-line and the propTypes are defined inside the function.