Day 1, Segment 4
Branch v2-9
Turn the dead button into a link
Using the Link module
// **** Landing.js ****
import React from 'react'
// 1. ++++
// import Link for handling links
import { Link } from 'react-router'
const Landing = React.createClass({
render () {
return (
<div className='landing'>
<h1>svideo</h1>
<input type='text' placeholder='Search' />
// 2. ++++
// use Link tag instead of <a>
<Link to='/search'>or Browse All</Link>
</div>
)
}
})
export default Landing
use <Link>
instead of <a>
to take advantage of browserrouterProps
In webpack config add json-loader because we want to load json files
// **** webpack.config.js ****
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/
},
// 1. ++++
{
test: /\.json$/,
loader: 'json-loader'
},
{
(questions... 09:00)Use the JSON data in Search.js
// **** Search.js ****
import React from 'react'
// 1. ++++ add data
import preload from '../public/data.json'
const Search = React.createClass({
render () {
return (
// 2. ++++
<div className='search'>
// just print out the data
<pre><code>{JSON.stringify(preload, null, 4)}</code></pre>
</div>
)
}
})
export default Search
What are the 3 parameters to JSON.stringify?
- the data you want to stringify
null
: the replacer function (maybe for passwords ?)- the indentation you want
Transform JSON data structure to markup (iterate/map)
Map a JSON array to markup. React knows how to iterate through arrays.
Explains Array.map (16:50)...
// **** Search.js ****
import React from 'react'
import ShowCard from './ShowCard'
import preload from '../public/data.json'
const Search = React.createClass({
render () {
return (
<div className='search'>
// 1. ++++
// map data structure to
// markup (component)
{preload.shows.map((show) => {
return (
<ShowCard key={show.imdbID} show={show} />
)
})}
</div>
)
}
})
export default Search
At this point you will get a warning in the console about unique keys... Will address this later. Array.map is not proprietary to React, contrary to ng-repeat. This is really a big difference.
Talks about arrow functions... (replaces the above code)
The Showcard component
render () {
// ES6 destructuring....
const { poster, title, year, description } = this.props.show
return (
<div className='show-card'>
// backticks from ES6
// (template literals)
<img src={`/public/img/posters/${poster}`} />
<div>
<h3>{title}</h3>
<h4>({year})</h4>
<p>{description}</p>
</div>
</div>
)
}
Whet to extract your code to a new component?
When the code in
Array.map((elem) => ...
grows too long is a good sign.Saves (extracts) the above component to ShowCard.js.
// **** ShowCard.js ****
import React from 'react'
const ShowCard = React.createClass({
render () {
const { poster, title, year, description } = this.props.show
return (
<div className='show-card'>
...
</div>
)
}
})
export default ShowCard
33:00Adding unique keys to list items
React needs to identify each element we output from a list structure, so that later it can re-render efficiently (eg. when doing a sort in the UI).
We need create a unique key for each repeating element.
Above in Search.js it's this
key={show.imdbID}
:
{preload.shows.map((show) => {
return (
<ShowCard key={show.imdbID} show={show} />
)
})}
The imdbID is surely unique, so a good key to use. You could also do:
{preload.shows.map((show) => <ShowCard key={show.imdbID} show={show} />
)}
But Brian argues that it's a bit too dense and hard to read and not ideal for maintainability.Proptypes
You declare what variables your component expects from its parent.
// **** ShowCard.js ****
import React from 'react'
// 1. ++++
const { string } = React.PropTypes
const ShowCard = React.createClass({
// 2. ++++
propTypes: {
poster: string,
title: string,
year: string,
description: string
},
render () {
const { poster, title, year, description } = this.props
return (
<div className='show-card'>
...
</div>
)
}
})
export default ShowCard
The reason for proptypes
Proptypes are not required by React. They serve as documentation so that you know what to pass to your component when you want to include it. And also for some weak type checking, debugging.
Make a proptype required
We can even make a proptype required :
title: string.isRequired
,What about other static type checking, like Flow?
Flow or Typescript is probably better, but he didn't want to use them for the workshop. They are more powerful than proptypes.
Proptypes are meant for development and not used, or checked in production. You can remove them in your build if you want.