Mosh React Tutorial (part 14)

1) mosh-react-tut-refactor-table-head

2) mosh-react-tut-extract-body

Refactoring Movies Table

So in movies.jsx, we see a lot of code in our render function. Let’s pull out table, as it makes up the bulk of our JSX.

In components, we create controlled MoviesTable.jsx. Basically, in order to extract code, we to first figure out what we want the refactoring to look like.
A closer look tells us that the table code involves three things:

1) the array that shows the data
2) the delete function
3) the sort function
4) Sort column that specifies the column text and sort order

All these handler objects and belong in movies.jsx. So as a controlled component, we should not have state, and simply show data via the props object.
Thus we need to make sure that in movies, we pass them in.

movies.jsx

So in MoviesTable, we extract them from the prop object and refactor like so:

Extracting Table Header from Movies Table

Notice MovieTable’s render is huge. Let’s extract the table header out.
We want to create a table header component in the render where we do something like this:

We had a string of paths and names in literal strings. So we first create an array to depict this:

We already have sortColumn object and onSort function in props, so we can directly pass it into TableHeader component.
thus, when we write our TableHeader component, we get the columns as an array and display their text. When they get clicked, we raise the sort function, which takes the prop object, and use the sortColumn property. Finally, it uses the passed in prop’s onSort function.

In src, components, common, create TableHeader.jsx file:

TableHeader.jsx

MoviesTable.jsx

Extracting Body

We also need to extract the boy from MoviesTable. The movies array is passed via the props data. We map through it and display tr for each movie.

For each tr (movie), we need to display the properties of the movie. In JS, we can do object[property] to access the value of the property in an object. However, if there are nested objects, we cannot go object[property.anotherProperty]. Therefore, “genre.name” won’t work. However, we can use lodash for this:

It takes the object ‘item’, then it gives the property path column.path. It will down into the object with the properties path and return you the value.

Notice that our output only has text data. Our ‘delete’ button is nowhere to be seen.
Hence, let’s add the delete button into our columns array.

MoviesTable.jsx

So now when we render this cell, we have to check for column.content. If its exists, its a delete button and returns JSX elements. If it doesn’t, then property is path and returns text and we use lodash for it:

For each row of data, we have to go through each column’s path (title, genre.name, numberInStock…) in order to display data.
The renderCell function to takes the item, column and display it (text or button…etc) as table data.

data is array of movies
columns is our defined array of property names, labels, and key/content JSX.

Hence, as go through each row, we must extract data like so:

TableBody.jsx

Let’s also update our handleDelete function in movies.jsx:

movies.jsx

MoviesTable.jsx