Learning React - Week 3
Tags: react, javascript, beginners
Published: 2017-08-03 04:29:46

---
title: Learning React - Week 3
published: true
description: Join me as I learn React in 30 minutes for 30 days with the 'React for Beginners' course by Wes Bos.
tags: react, javascript, beginners
---

This article originally appeared on [stef.ninja](https://stef.ninja/learning-react-week-3/).


This is the third post in a series of notes from the [React for Beginners](https://reactforbeginners.com/) course from [Wes Bos](https://twitter.com/wesbos) that I am working through. This is an **AWESOME** course and I highly recommend it to anyone looking to learn React. 

You can find more notes in [Week 1](/learning-react-week-1/) and [Week 2](/learning-react-week-2/) of the series.

###Day 15: Display Data from the State
We have the sample fish data saved in our state. Let's get these fish displaying in the UI.

JSX doesn't have any loops or logic built in so to combat this we can use regular javascript (by encapsulating it in {}). To display a list of our sample fish we will map over the entire list of keys within the `fish` object like so:
```
<ul class="list-of-fishes">
  {
    Object
      .keys(this.state.fishes)
      .map(key => <Fish key={key} />)
  }
</ul>
```
Wes gives a good tip around [ES6 destructuring](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) that means when we are referencing the props that are sent down to the child we don't have to repeat ourselves with `this.props` all of the time. 
```
const {details} = this.props;
```
Further reading: Wes Bos has [A Dead Simple intro to Destructuring JavaScript Objects](http://wesbos.com/destructuring-objects/)

######To Do:
- Pass the details about each fish down to the Fish component via the `details` prop. Hint: `details={this.state.fishes[key]}`
- Use the formatPrice function in the helper file to format the Price detail.
- Make a component (Fish.js) that displays the data for each fish. Return this all in a `<li>`.
- Iterate through a list of the sample fish in the fish object & display the Fish component.

######Today the app looks like:
![App on Day 15 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day15-1500008561302.png)

*[Video 15: Displaying State with JSX]*

###Day 16: Updating State
Today we're linking up the `Add To Order` button so it actually adds the corresponding fish to the state.

The button has an awesome feature where it dynamically changes depending on whether a fish is available or not. To do this we will be implementing some logic around `details.status` using a [ternary operator](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator).
```
const isAvailable = details.status === 'available';
const buttonText = isAvailable ? 'Add To Order' : 'Sold Out!';
```


######To Do:
- Change the content of our `Add To Order` button to be dynamic depending on the `details.status`.
- Change the button to be disabled if the fish is unavailable.
- Add `addToOrder` method on the app component.
//Take a copy of the state
//Update the new number of fish ordered e.g `order[key] = order[key] + 1 || 1;`
//Update state.
- Bind the method to the app component.
- Pass the `addToOrder` down to our child via props.
- Add an `onClick` handler to the button that updates the state of the order. Note: To do this we will need a reference to the key. Pass this down as a prop on the Fish component.

***Quick Note: I send these notes over to my best dev friend [Mark](https://twitter.com/markacola) to read through before publishing & he always gives me great notes on things that I'm not 100% across. Below are his notes on the function that we used to update the number of fish ordered:***

>If the `key` isn't set in `order` then `order[key]` will return `undefined`, which means `order[key] + 1` => `undefined + 1` => `NaN`, and because `NaN` is falsey the `1` in the `NaN || 1` expression is returned. It is small but important to understand the sequence of transforms that the data goes through so you don't get tripped up later on.


######Today the app looks like:
![App on Day 16 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day15-1500008561302.png)

*It looks exactly the same as yesterday because we didn't make any UI changes.*

*[Video 16: Updating Order State]*


###Day 17: Display State via JSX

In today's lesson we are taking the `order` state that we have been working with and injecting it into the UI via JSX.

This is the first time that we are calling another method within the render method to handle a fair bit of our JSX output. Wes mentions that this can be done using another component but he has opted to an additional method within the Order.js component to keep it simpler (no need to hand down props once we bind it).


######To Do:
Todays Goal: Display fish order via `Order.js`. This component needs to include the number of lbs, name of fish, total cost of each line item, and total cost. We will do this by:

- Passing the `fishes` & `order` state to the order component via props.
- Create a running total price of all of the fish included in the order.
- Importing and using the `formatPrice()` function from the helpers file.
- Creating a `renderOrder()` function within the Order component to handle the JSX returned for each fish within the order. This can be called from within the `render()` function like this: `{orderIds.map(this.renderOrder)}`
- Bind our custom method to this via a constructor.
- Remember to add the key to all list items to ensure that React can reference them.

######Today the app looks like:
![App on Day 17 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day_17_catch_of_the_day-1500604761179.gif)

*[Video 17: Displaying Order State with JSX]*


###Day 18:

Persiting data requires a backend service. In this lesson we use [Firebase]() from Google as our backend service.

It uses [HTML5 Websockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) which Wes was pretty excited about but I had to do some research around. This video was a really good explanation of it with an example: [Introduction to Websockets and Firebase - How to Build Real-Time Apps](https://www.youtube.com/watch?v=ZSRNNqh5Xo8)

So with Firebase we have a realtime backend database. A great feature of the Firebase Realtime Database is that it is basically a giant object. Which syncs perfectly with React State also being an object.

During this lesson we also explored the [React Lifecycle Hooks](https://facebook.github.io/react/docs/state-and-lifecycle.html). These lifecycle methods offer us different entry points into a component.

We focussed on the componentWillMount method that is invoked before the initial component is rendered. This is a great time to sync the database object with our state object. It also has a coupled componentWillUnmount method that allows us to break the connection.

![Code in App.js used to connect to the database via re-base](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day_18_componentWillMount-1500611498129.png)

#####To Do:

- Sign up for a Firebase account.
- Create a new Project in Firebase.
- Edit the Realtime Database rules to be less secure (don't worry we will fix this us in the authentication lesson set for day 24). Set the Realtime Database rules to:

```
{
  "rules": {
    ".read": true,
    ".write": true
  }
}
```

- Use the [re-base](https://www.npmjs.com/package/re-base) package to implement Firebase into the React app with the following being entered into `base.js`:

```
import Rebase from 're-base';

//Get some information from your Firebase project
const base = Rebase.createClass({
    apiKey: YOUR API KEY,
    authDomain: YOUR AUTH DOMAIN,
    databaseURL: YOUR DATABASE URL,
  });

export default base;
```

- import `base` into the App
- Hook into the `componentWillMount()` lifecycle method to sync the App state with the Firebase Realtime database.



######Today the app looks like:
![App on Day 18 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day18_firebase-1500611512648.gif)

*[Video 18: Persisting our State with Firebase]*

###Day 19: Persisting State with localstorage

In todays lesson we explored persisting the state of our order via [HTML5 Local Storage](https://www.w3schools.com/html/html5_webstorage.asp).

Local Storage allows us to store the data associated with the order within the browser. It is a good option for the order to be stored in because it is secure, local and doesn't impact on website performance.

Local Storage uses key value pairs. The value only accepts numbers, strings or booleans. This means we need to transform our order object into a string. We can do this via the `JSON.stringify()` method (you can always turn it back with `JSON.parse()`).

We were also using the [React Lifecycle Methods](https://facebook.github.io/react/docs/react-component.html) in this lesson. Specifically the `componentWillUpdate` method that is invoked immediately before rendering when new props or state are being received. This method also isn't called for the initial render which suits this data object (order) well.

The Lifecycle methods on `<App>` currently look like:
![Lifecycle methods](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day19_lifecycle-1500620253486.png)

#####To Do:

- Pass down all of the params to the `<Order>` component.
- Hook into the `componentWillUpdate` method and set the localStorage to our `order` state.
- Hook into the `componentWillMount` method (already called) and check whether there is any order in localStorage.
- If there is an order saved in localStorage then update the <App> order state.

######Today the app looks like:
![App on Day 19 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day_19_localstorage-1500620458400.gif)

*[Video 19: Persisting Order State with localstorage]*

###Day 20: Live State Editing with Bi-directional State
Today was a pretty involved lesson. We managed to set up state editing via the inventory management from the UI of the app. 

First we needed to create a form for each of the fish objects within our state. This was done in the `Inventory` component via a new `renderInventory()` method we created:

![renderInventory method that we created today](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day20_renderInventorymethod-1500872408641.png)

Once the form had been created we needed a new method to handle the updates. This was done with the `handleChange` method that we created:

![handleChange method that we created today](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day20_handlechange-1500872560726.png)

The final method we added was on the App component and it made the magic happen. The state is only updated via the App component so this is why everything had to be passed up there. 

This pattern of copy the current state, overwrite the section that has changed, then update the state is becoming a go to when writing React code. 

![updateFish method that we created on the App component today](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day20_updatefish-1500872669590.png)

---
######Note from Mark:

Passing each of these functions inline is a great opportunity to use [memoization](https://en.wikipedia.org/wiki/Memoization). Currently, with every change that is put through any of those inputs all children are re-rendered. This isn't a giant performance suck at this level as they are only inputs (not large components) but it is good to get into the habit of memoization early. 

We used [lodash.memoize](https://lodash.com/docs/#memoize). This is the improved functions that we worked out:

![Improved function performance using memoize](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day20_lodashmemoize_improvement-1500879417158.png)

Further reading on this:
[Lodash memoize](https://lodash.com/docs/#memoize)
[The Big O Notation](https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/)

#####To Do:
- Loop over all of the fish within the state and output an inventory management form (much like the new fish form)
- Pass `fishes` down to `<Inventory />` via props.
- Create `renderInventory()` method that will handle all of the form rendering.
- Add the current values of the fish (from state) into each section. 
- Data bind the values so each time an edit is made this is reflected in the state (and on the Firebase database) (remember to use `defaultValue` instead of `value` so that the field is mutable). Use `onChange{(e) => this.handleChange(e, key)}`. 
- Create a custom `handleChange()` method and bind it using the constructor. Within that method take a copy of the fish state. Then use the computed target to update ONLY the element that has changed:

```
handleChange(e, key) {
  const fish = this.props.fishes[key];
  //Copy the fish and update it with new data
  const updatedFish = {
    ...fish,
    [e.target.name]: e.target.value
  }
  this.props.updateFish(key, updateFish);
}
```
- Pass the updated fish up to the `<App />` component. 
- Create a custom method to set the state of the fishes to the updated fish (use `updateFish()`).
- Make the `updateFish()` available to the `<Inventory />`


######Today the app looks like:
![App on Day 20 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day20-1500872206503.png)

*[Video 20: Bi-directional Data Flow and Live State Editing]*


###Day 21: Deleting Items from State
[CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) (or Create, Read, Update and Delete) is the basic functions required for persistent storage. We have already worked through creating objects to save in the state, reading the state and updating the state. In today's lesson we focus on deleting objects from state.

To do this we run through a similar pattern to the one I highlighted yesterday:
```
removeFish(key) {
  //Copy the current state
  const fishes = { ... this.state.fishes };
  //Delete the specific fish
  //Note: 'null' needs to be used because of Firebase
  fishes[key] = null;
  //Set the State
  this.setState({ fishes });
}
```

That's it. The fish is now deleted. Obliterated from existence.

#####To Do:
- Create a `removeFish` method that deletes a specific fish from the state.
- Create a `Delete Fish` button within the `renderInventory` JSX
- Link the `onClick` handler up to the `removeFish` method.

######Today the app looks like:
![App on Day 21 of the React for Beginners Course](https://s3-ap-southeast-2.amazonaws.com/ghost-blog-stef-ninja/2017/07/day21_remove-1500875398012.gif)

*[Video 21: Removing Items from State]*

---
Read more in this series: [Week 1](https://stef.ninja/learning-react-week-1/), [Week 2](https://stef.ninja/learning-react-week-2/), and [Week 4](https://stef.ninja/learning-react-week-4/) **Or** get the [React for Beginners Course](https://reactforbeginners.com/) for yourself.