+ - 0:00:00
Notes for current slide

title image - https://unsplash.com/photos/tjX_sniNzgQ

Contact Info Thanks:

  • conference
  • organizers
  • sponsors
  • you!

timekillers:

  • where from?
  • stickers!
  • favorite talks
  • favorite speakers
  • poll about intro
  • stand up & stretch
  • high fives
Notes for next slide

title image - https://unsplash.com/photos/tjX_sniNzgQ

Contact Info Thanks:

  • conference
  • organizers
  • sponsors
  • you!

timekillers:

  • where from?
  • stickers!
  • favorite talks
  • favorite speakers
  • poll about intro
  • stand up & stretch
  • high fives

Setup

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Setup

stevenhicks.me/your-first-react-app-setup

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

intro & setup: 0:00 - 0:?? [timing]

git, node, npm, & repo

If you cloned before yesterday - pull latest!

If not set up, do this while I talk! (point out url)

If lots didn't do it:

We'll take 5 minutes to do this now.

I'll walk around and help where I can, but please don't hesitate to ask your neighbors if you're having problems.

TIMEBOXED TO 5 MINUTES.

About

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

Me

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

Me

Steven Hicks

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

Me

Steven Hicks

Me Me

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

I am standing right in front of you so you can tell what I look like

But on the left is what my 8 year old daughter Olivia thinks I look like

On the right is what my 10 year old daughter Lila thinks I look like

and if you think this is just an excuse to talk about my kids

and show you their artwork

You are correct.

Senior Engineer

our mission is to expand the art market,

and we're doing that with a platform for collecting and discovering art.

About

This Workshop

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

Me: Talk

You: Exercise

Me: Recap

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

17 exercises

About

This Workshop

Goal: Survey React Landscape

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

because you're going to need more than react to build an app

I want you to be prepared to build your next app.

About

This Workshop

Instructions: README.md

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

👉: Specific Task

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

Answers: SOLUTIONS.md

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

linked from README

About

This Workshop

Answers: SOLUTIONS.md

Answers: ./complete

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

linked from README

view our kitten friends

change theme

details about a kitten

About

This Workshop

Schedule

  • 8:00 - ??? Setup, Intro, Modern JavaScript, JSX, React Components, Composition, CSS, Routing
  • ??? - ??? Lunch
  • ??? - 3:00 State Management, Loading Data, Legacy Components, Testing
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Now is your chance to break!

About

This Workshop

Collaborative

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

Collaborative

  • You + me
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

Collaborative

  • You + me

  • You + your neighbor

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Teaching is one of the best ways to learn

(meet neighbors comes later)

About

This Workshop

"Done" Indicator

Post-it on the back of your laptop

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

Feedback

Green = Good; Yellow = Okay; Pink = Bad

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

This Workshop

Feedback

Green = Good; Yellow = Okay; Pink = Bad

Comments Welcome!

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Q's:

How did you like the format?

Amount & depth of content?

About

You

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React devs?

JavaScript/UI devs?

What UI tools are they using? Angular? Ember? jQuery?

About

You

Meet your neighbors!

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

About

You

Meet your neighbors!

  • Name
  • Where you're from
  • What you do
  • What you're excited about
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

History

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

I've been working on front-end web apps for 20 years

I've built them with many different kinds of JavaScript tools

History

Plain JavaScript

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

History

Plain JavaScript

  • 👎 Hard to write
  • 👎 Hard to scale
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Hard to scale the codebase

If you got it to work, you shipped it.

History

jQuery

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

History

jQuery

  • 👍 Easy to write
  • 👎 Hard to scale
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

History

MVC/MVVM

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Angular 1, Knockout, Backbone, ...

History

MVC/MVVM

  • 👍 Easy to scale
  • 👎 Hard to write
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Angular 1, Knockout, Backbone, ...

sometimes...

History

MVC/MVVM

  • 👍 Easy to write
  • 👎 Hard to scale
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

other times.

Regardless, an improvement!

History

React

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

My favorite way to build a web app

History

React

  • 👍 Easy to write
  • 👍 Easy to scale
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

My favorite way to build a web app

When we talk about tools, it's helpful to know what problem they solve.

That's the problem react solves...

React

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

There are a bunch of things that react is...

the most significant one, for me, is...

React Is

Simplicity

+

Scalability

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React makes it easy to scale simple, understandable code to a large app.

simplicity: hope you can experience today

React Is

Scalable

30,000

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React Is

Scalable

30,000

The number of React components in Facebook's codebase

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

scalability:

number of components in Facebook's codebase

source: https://medium.com/@dan_abramov/hey-thanks-for-feedback-bf9502689ca4

React Is

A JavaScript library for building user interfaces

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

from their site

dumb - of course that's what it is

but there's meaning here - it is ONLY a UI framework

React Is

The V in MVC

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

And nothing more

(maybe the C)

React Is

The V in MVC

Angular : monolith ::

React : microlibraries

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React Is

The V in MVC

Choosing between Angular and React is like choosing between buying an off-the-shelf computer and building your own with off-the-shelf parts.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React Is

Declarative

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

What does that mean?

Well, it means we write code that says WHAT to display

not HOW to display it

React Is

Declarative

How do you get to my house?

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

imperative

declarative - abstracts the imperative

Obviously some code, at some point,

has to be written on HOW to display

React Is

Declarative

Imperative code is abstracted

so that we can call it declaratively

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

But we abstract the imperative code

So our app can call it declaratively.

React Is

Declarative

var kittensComingToMyParty = [];
for (var i = 0; i < kittens.length; i++) {
var kitten = kittens[i];
if (kitten.rsvp === true) {
kittensComingToMyParty.push(kitten);
}
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

if I wanted to know which kittens were coming to my party, I could write code like this

imperative

React Is

Declarative

var kittensComingToMyParty = [];
for (var i = 0; i < kittens.length; i++) {
var kitten = kittens[i];
if (kitten.rsvp === true) {
kittensComingToMyParty.push(kitten);
}
}
var kittensComingToMyParty = kittens.filter(
kitten => kitten.rsvp === true);
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

if I wanted to know which kittens were coming to my party, I could write code like this

imperative

...

declarative

...

Why do we care about this?

React Is

Declarative

Declarative views make your code more predictable and easier to debug.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

When your code is less worried about HOW to do things,

it's less cognitive load on the reader.

React Is

Component-Based

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React Is

Component-Based

Build encapsulated components that manage their own state, then compose them to make complex UIs.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

(read)

...

We'll talk more about components in a bit

...

but before we do, we need to take a step backwards from even React

Let's talk about JavaScript.

JavaScript

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

There are some JS tools we're going to be using today

that you might have heard of

JavaScript

1. npm

Node Package Manager

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

problem solved: makes it easier to manage dependencies

JavaScript

npm

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

looking at the history of building web apps

JavaScript

npm

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

oldest way (1): download a library & put it in a folder

JavaScript

npm

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

old way (2): bower

JavaScript

npm

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

new way (3): npm

...

we're going to use npm for a couple things

  1. to collect & organize our dependencies

to use npm, you need a manifest to identify all your dependencies.

this is the package.json.

A cool thing the package.json also allows you to do is define scripts

so 2. we'll run app & tests, via npm scripts

rolling 28 day downloads - over 25 million

NPM usage is growing at a crazy rate

Tons of packages

That means the user might have to download a ton of different libraries to their browser to run our app.

so...

JavaScript

2. webpack

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

problem solved: large javascript downloads

removes unused code

compresses & minifies our bundle

good development experience

JavaScript

3. ES-modern

ES6+, ES2015+, ...

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

problem solved: JavaScript for the web didn't change at all between 1999 and 2009.

It changed very little from 1999 to 2015.

But we've learned a lot about programming languages since 1999.

Especially the importance of readability & developer experience.

We're now getting new versions of JavaScript via the EcmaScript specification

And it's bringing lots of developer-friendly changes.

...

Let's look at some of those changes, because there are some that impact the way we can write React code.

Exercise 1

Modern JavaScript: Modules

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

git checkout master

git pull

npm run test-exercise-1

Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components

The "Component" Mindset

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components are React's biggest contribution to web dev

It's a mindset shift

When we were doing MVC/MVVM,

we used to think in terms of "controllers" and "views"

We did this because of the principle of "separation of concerns"

But React says controllers & views are the same concern - a component.

twitter

so instead of this page having a controller & a view,

it really has a handful of components

building blocks

and each of those components is a concern

and it goes further than that -

each of those components is composed...

of more components

Exercise 2

Identifying Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components

Exercise 2

Identify Components

Draw the boundaries of individual components on each page

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components

Suggestions

Favor small components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

The deconstruction of UI's into small components is crucial to successful React development.

Components

Suggestions

Components are more about isolation than reuse

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

It's easy to think we are doing this to make reuse easier

But it's really more about isolation

Components

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components are like building blocks.

Smaller ones that do fewer things are easier to understand

And easier to assemble (so they aid reuse).

Components + React

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Components Are Functions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Component Functions

import React from 'react';
function FriendsList {
// ...Details about this component
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • import react
  • FriendsList component is a function

Ideally, these component functions should be pure

...

2 parts to "pure":

1.doesn't modify state

2.returns same value with same args

...

let's look at some examples of pure & impure functions

to give you clarity on the difference

Components + React

Pure Functions

function add(a, b) {
return a + b;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Pure Functions

function add(a, b) {
return a + b;
}
Pure 😊
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

our example from earlier

pure

doesn't modify the state of anything

returns the same result each time

Components + React

Pure Functions

function now() {
return new Date();
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Pure Functions

function now() {
return new Date();
}
Impure 😟
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

impure

it doesn't return the same result each time

Components + React

Pure Functions

function Friend() {
this.x = this.x - 1;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Pure Functions

function Friend() {
this.x = this.x - 1;
}
Impure 😟
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

impure

it modifies the state of the component

note: I used the worried face, not sad face

cuz impure functions cause you to worry about side-effects & unpredictability

Components + React

Inputs

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Inputs

Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Inputs

props

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

component = function of props, the result of which is output to browser

Components + React

Inputs

props

function Friend(props) {
console.log(props.name, props.url);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • taking in props

Components + React

Output

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

How do we actually get something on the screen?

we know it goes in our function

but what actually renders markup?

Components + React

Output

React.createElement()

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Output

createElement()

function Friend() {
return React.createElement('div');
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

create a simple element

Components + React

Output

createElement()

function Friend() {
return React.createElement('div');
}
<div />
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

create a simple element

emits a div

Components + React

Output

createElement()

function Friend() {
return React.createElement('button');
}
<button />
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

other element types

Components + React

Output

createElement()

function Friend() {
return React.createElement('div', { id: 'friend-wrapper' });
}
<div id="friend-wrapper" />
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • 2nd argument (optional): "props"

  • props to apply to rendered element

  • pass as many props as you want

Components + React

Output

createElement()

function Friend() {
return React.createElement('div', { id: 'friend-wrapper' }, 'Hi!');
}
<div id="friend-wrapper">Hi!</div>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • 3rd arg (optional): children

  • text node, in this example

Components + React

Output

createElement()

function Friend(props) {
return React.createElement(
'div',
{ id: 'friend-wrapper'},
props.name
);
}
<div id="friend-wrapper">Potatoes</div>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • props as text node!

  • Outputs are re-rendered as their inputs change

  • React handles this for you!

Components + React

Output

createElement()

function Friend(props) {
if (props.name === 'Potatoes') {
return React.createElement('div', null, 'We`re best friends!');
}
return React.createElement('div', null, 'We`re not best friends.');
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

since our component is pure javascript

we can do things like conditional rendering

Components + React

Output

createElement()

function Friend(props) {
if (props.name === 'Potatoes') {
return React.createElement('div', null, 'We`re best friends!');
}
return React.createElement('div', null, 'We`re not best friends.');
}
<div>We`re best friends!</div>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

since our component is pure javascript

we can do things like conditional rendering

  • shows when name is Potatoes

Components + React

Output

createElement()

function Friend(props) {
if (props.name === 'Potatoes') {
return React.createElement('div', null, 'We`re best friends!');
}
return React.createElement('div', null, 'We`re not best friends.');
}
<div>We`re best friends!</div>
<div>We`re not best friends.</div>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

since our component is pure javascript

we can do things like conditional rendering

  • shows when name is Potatoes
  • shows in other cases

Components + React

Output

createElement()

function Friend(props) {
return React.createElement(
'div',
null,
React.createElement('h1', null, 'Hello, ' + props.name)
);
}
<div>
<h1>Hello, Potatoes</h1>
</div>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • nest calls to React.createElement

  • emits nested elements

...

you can build an entire React app using React.createElement.

but here's the problem with react.createlement.

Most of the things we render to a webpage aren't 1 or 2 html elements.

Components + React

Output

createElement()

<div id="friend">
<div id="title">
<h1>Potatoes</h1>
<h2>4 months</h2>
</div>
<div id="photo">
<a href="/friends/potatoes">
<img src="/friends/potatoes/image" alt="Potatoes" />
</a>
</div>
</div>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

They're often more like this - and this is even on the small side.

(describe html)

...

here's what our createElement statement looks like for this -

This is not that easy to read

I'd even describe it as "barfy"

...

this is where another library comes in

Components + React

Output

JSX

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Output

JSX

JSX is an XML-like syntax extension to ECMAScript without any defined semantics.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

It's XML in Javascript

...

here's what it looks like

Components + React

Output

JSX

function Friend() {
return React.createElement('div');
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

as createElement: An example from earlier.

Components + React

Output

JSX

function Friend() {
return React.createElement('div');
}
function Friend() {
return <div />;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

as createElement: An example from earlier.

as jsx: Looks like the markup we want to render!

Components + React

Output

JSX

function Friend(props) {
return React.createElement(
'div',
null,
React.createElement('h1', null, 'Hello, ' + props.name)
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

another example - more complicated

Components + React

Output

JSX

function Friend(props) {
return React.createElement(
'div',
null,
React.createElement('h1', null, 'Hello, ' + props.name)
);
}
function Friend(props) {
return (
<div>
<h1>Hello, {props.name}</h1>
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

another example - more complicated

{} - you want to evaluate a js expression there

...

why would we do this to ourselves?

why put xml in javascript?

it's like a horror film from 2004.

Components + React

Output

JSX

React.createElement Is Verbose

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

remember our most complicated createElement example ?

Components + React

Output

JSX

function Friend(props) {
return (
<div id="friend">
<div id="title">
<h1>{props.name}</h1>
<h2>{props.age}</h2>
</div>
<div id="photo">
<a href={'/friends/' + props.id}>
<img src={props.profileImageUrl} alt={props.name} />
</a>
</div>
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Output

JSX

Optional

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

you can build an entire app with createElement

we'll use it today because it makes your code much more readable

...

who still doesn't like this idea?

(poll for separation of concerns)

REPEAT THEIR ANSWER!!!!

Components + React

Output

JSX

Separation Of Concerns

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React

Output

JSX

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

React components with JSX look like HTML + JS

the instinct is to separate them

A component's concern is rendering

It's that friend

or that list of friends

Components + React

Output

JSX

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

And it takes HTML + JS to render them

You can think of components changing the way we're slicing the app

...

The rub...

Components + React

Output

JSX

Browsers Just Don't Understand

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

So we have to transpile.

It is an extra step between our code & the browser.

But remember, we're already using webpack to minimize our dependencies from npm

Components + React

Output

JSX

function Friend(props) {
return (
<div id="friend">
<div id="title">
<h1>{props.name}</h1>
<h2>{props.age}</h2>
</div>
<div id="photo">
<a href={'/friends/' + props.id}>
<img src={props.profileImageUrl} alt={props.name} />
</a>
</div>
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Does anyone want to guess what this transpiles to?

Exercises 3 & 4

Modern JavaScript: Working With Variables

JSX Fundamentals

stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • New features to make it easier to work with objects

  • different things you can do in jsx

Components + React + JSX

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

A component can return 5* things

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

can return five things*

(actually more but we're only going to talk about 5)

Components + React + JSX

Can return

1. Element/React Component

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Can return

1. Element/React Component

function Friend(props) {
return (
<div>
{props.name}
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

return a DOM node

Components + React + JSX

Can return

1. Element/React Component

function Friend(props) {
return (
<FriendImage friend={props.friend} />
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

return another user-defined component.

Components + React + JSX

Can return

2. Array

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Can return

2. Array

function Friend(props) {
return [
<FriendImage friend={props.friendA} />,
<FriendImage friend={props.friendB} />,
]
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Let you return multiple elements

it's more valuable than you think

this example is not something you'll do a lot of...

Components + React + JSX

Can return

2. Array

function Friend(props) {
return props.friends.map(friend =>
<Friend name={friend.name} />
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

but this is!

mapping from an array to an array of react components.

Components + React + JSX

Can return

3. Fragment

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Can return

3. Fragment

import React, { Fragment } from 'react';
function Friend(props) {
return (
<Fragment>
<FriendImage friend={props.friendA} />
<FriendImage friend={props.friendB} />
</Fragment>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Nicer syntax than returning an array,

if you have multiple items to return

Fragment does not render anything to the DOM

It used to be that you had to wrap things in a div, instead of a fragment (pollution)

Components + React + JSX

Can return

3. Fragment

import React from 'react';
function Friend(props) {
return (
<>
<FriendImage friend={props.friendA} />
<FriendImage friend={props.friendB} />
</>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Shortcut for rendering a fragment

  • don't need to import Fragment
  • "empty" tag

Components + React + JSX

Can return

4. String/Number

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Can return

4. String/Number

function Friend(props) {
return props.name;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

These are rendered as text nodes in the DOM.

Components + React + JSX

Can return

5. null

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Can return

5. null

function Friend() {
return null;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

renders nothing.

you could do this, but you won't.

..

you WILL do this, though

Components + React + JSX

Can return

5. null

function Friend(props) {
if (props.isLoading) {
return null;
}
return <div>{props.name}</div>
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

early-exit from a component

Exercise 5

What can a component render?

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

the different types of things a component can render

Components + React + JSX

Common Errors

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Common Errors

Component Names Must Be Capitalized

The tag < friendsList > is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.`

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Common Errors

Components Must Return Something

Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.`

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Components + React + JSX

Common Errors

Components Must Return Something

function Friend(props) {
<div>{props.name}</div>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

you'll write components like this, many times

the problem?

Components + React + JSX

Common Errors

Components Must Return Something

function Friend(props) {
return <div>{props.name}</div>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

it's not actually RETURNING the jsx.

Components + React + JSX

Common Errors

Components Must Return Something

export default function(props) {
return
<div>
{props.name}
</div>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

another thing you'll do plenty of times

what's wrong?

that return is returning!

Components + React + JSX

Common Errors

Components Must Return Something

export default function(props) {
return (
<div>
{props.name}
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

we need parens on the same line, to tell it not to just terminate that statement.

with modern editors this is harder to do now than it was a year ago, but still something to be aware of.

Props

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Props

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Our Component Inputs

Props

Should Never Be Modified

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Props

Should Never Be Modified

function Friend(props) {
props.name = 'Mr. Cat The Mystery Cat';
return <div>{props.name}</div>
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

If a prop needs to be changed...

it's probably state (not a prop)

Props

Syntax

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

We've seen in some examples already

Props

Syntax

function Friend(props) {
if (props.isLoading) {
return null;
}
return <div>{props.name}</div>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

We've seen in some examples already

props arg is passed in

and it contains a property for each individual prop

Props

Syntax

function Friend(props) {
const { isLoading, name } = props;
if (isLoading) {
return null;
}
return <div>{name}</div>
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

object destructuring

Props

Syntax

function Friend({ isLoading, name }) {
if (isLoading) {
return null;
}
return <div>{name}</div>
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

argument destructuring

Props

Default Props

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

specify defaults for props

Props

Default Props

function FriendProfile({ name, image }) {
return <img alt={name} src={image} />
}
FriendProfile.defaultProps = {
image: 'http://placekitten.com/200'
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

specify defaults for props

assign to the function afterward

Props

Default Props

function FriendProfile(
{
name,
image = 'http://placekitten.com/200'
}
) {
return <img alt={name} src={image} />
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

with argument destructuring

Props

Children

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Every component gets a special prop

Props

Children

function Title({ children }) {
return <h1 id="title">{children}</h1>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Every component gets a special prop

...

example: a Title component

Title component gets children passed in

Props

Children

function Title({ children }) {
return <h1 id="title">{children}</h1>;
}
<Title>Hello, friends!</Title>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Every component gets a special prop

...

example: a Title component

Title component gets children passed in

...

the children are everything inside of the Title element

Props

Children

function Title({ children }) {
return <h1 id="title">{children}</h1>;
}
<Title>Hello, friends!</Title>
<h1 id="title">Hello, friends!</h1>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Every component gets a special prop

...

example: a Title component

Title component gets children passed in

...

the children are everything inside of the Title element

...

this is what gets emitted to the DOM

note the children being wrapped inside the div

...

children prop is really powerful.

Props

Children

Composition

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

allows us to compose our components, instead of inherit them

easier to assemble building blocks

easier to refactor/change

(less brittle than inheritance)

Exercise 6

Composition & props.children

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

building components that aid composition

Props

Prop Validation

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

With so many components flying around, nested deeply inside each other...

how do we make sure our component is getting the data it needs?

Props

PropTypes

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Props

PropTypes

Optional

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

You don't need them to build an app

Props

PropTypes

npm install --save prop-types
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Used to be part of React

Now an external library

Props

PropTypes

import propTypes from 'prop-types';
function FriendProfile({ name, image }) {
return <img alt={name} src={image} />;
}
FriendProfile.propTypes = {
name: propTypes.string.isRequired,
image: propTypes.string.isRequired,
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

syntax: append after

Props

PropTypes

Friends.propTypes = {
friends: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
})
).isRequired,
};
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

arrays

shapes

isRequired

Props

PropTypes

Validate At Run-Time

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

You fire up a browser, view your component, & see an error in the console

Props

PropTypes

index.js:1446 Warning: Failed prop type: The prop `age` is
marked as required in `FriendProfile`, but its value is `undefined`.
in FriendProfile (at Exercise.js:10)
in Friends (at Exercise.js:5)
in Exercise (at App.js:13)
in div (at App.js:12)
in div (at App.js:7)
in App (at exercise-6/index.js:6)
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

This is what the error looks like

Props

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Props

Suggestions

Turn off propType validation in production

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

propTypes are a development tool

Props

Deeper Learning

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Props

Deeper Learning

TypeScript

interface FriendProfileProps {
name: string;
image: string;
}
function FriendProfile(props: FriendProfileProps) {
const { name, image } = props;
return <img alt={name} src={image} />;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • define interfaces of the required props
  • ts compiler becomes part of build step
  • will give you a compile-time error if it doesn't get those types
  • can use for more than react components

Props

Deeper Learning

Flow

type FriendProfileProps = {
name: string;
image: string;
}
function FriendProfile(props: FriendProfileProps) {
const { name, image } = props;
return <img alt={name} src={image} />;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • looks similar to ts

  • also compile-time

  • better tooling from typescript

...

If I were starting a new project, I would use TypeScript.

CSS

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Styles Go With Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

most important thing to know:

gone are the days of one massive stylesheet for an entire app

with react's focus on components, we want to put our styles with our components.

...

A few different approaches.

CSS

Method 1: Component CSS Files

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Component CSS Files

.friend {
color: blueviolet;
border-bottom: 1px solid blueviolet;
}

friend.css

import './friend.css';
function Friend({ name }) {
return <div className="friend">{name}</div>
});

friend.jsx

stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • css file: specific to friend component
  • friend component imports css file
  • className refers to class from .css file

Note that this works because we're using webpack with style-loader

(it effectively turns our css into a js object that we can import)

CSS

Method 2: CSS Modules

https://github.com/css-modules/css-modules

CSS Modules

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

the problems css-modules aims to solve:

CSS

CSS Modules

.friend {
color: blueviolet;
border-bottom: 1px solid blueviolet;
}

friend.css

import styles from './friend.css';
function Friend({ name }) {
return <div className={styles.friend}>{name}</div>
}

friend.jsx

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

what it looks like in your code:

  • css file specific to friend
  • import into component as default dep
  • reference classname as a property on styles

CSS

CSS Modules

.Friend__friend__31BtE {
color: blueviolet;
border-bottom: 1px solid blueviolet;
}

CSS

<div class="Friend__friend__31BtE">Mr. Turtle</div>

HTML

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

what gets shipped to the browser

  • name-mangled

CSS

Method 3: Styled Components

styled-components.com

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Styled Components

import styled from 'styled-components';
const brandColor = 'blueviolet';
const StyledFriend = styled.div`
color: ${brandColor};
border-bottom: 1px solid ${brandColor};
`;
function Friend({ name }) {
return <StyledFriend>{name}</StyledFriend>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • import styled
  • styles are in the component!
  • tagged template literal to create styled component
  • styled component in return statement

CSS

Styled Components

.31bte {
color: blueviolet;
border-bottom: 1px solid blueviolet;
}

CSS

<div class="31BtE">Mr. Turtle</div>

HTML

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

shipped to the browser

Exercise 7

CSS: Three Ways To Style

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Deeper Learning

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

soooo many ways

CSS

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Suggestions

Find the way that works for you, and do it unapologetically

Scott Hanselman

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

People who use css-in-js REALLY like it

I've never felt like managing CSS scope was a problem

But it might depend on what you're building -

Component library probably warrants css-in-js

CSS

Suggestions

Separation Of Concerns

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Suggestions

Separation Of Concerns

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

CSS

Suggestions

Styling Belongs To Your Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

the important thing is that you have component-based css

via imported css, imported scss, css modules, css-in-js....

The main takeaway is that styles are not a separate concern from the rest of the component.

Routing

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Routing

React Router

https://reacttraining.com/react-router/

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

...some things about react router:

Routing

React Router

Declarative

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Routing

React Router

Declarative

import { BrowserRouter, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" component={FriendsList} />
<Route path="/lists/:id" component={ListDetail} />
<Route path="/friends/:id" component={FriendDetail} />
</div>
</BrowserRouter>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • imports
  • browserrouter wrapper
  • routes specify which components handle which urls

Routing

React Router

Routes Are Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Almost everything in react router is a component

Routing

React Router

Routes Are Components

import { BrowserRouter, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" component={FriendsList} />
<Route path="/lists/:id" component={ListDetail} />
<Route path="/friends/:id" component={FriendDetail} />
</div>
</BrowserRouter>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Almost everything in react router is a component

Routing

React Router

Routes Are Rendered Dynamically

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

in most SPA frameworks, you define routes up front

with React Router, routes are part of the component tree

so the routing happens as things are rendering

Routing

React Router

Routes Are Rendered Dynamically

import { BrowserRouter, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" component={FriendsList} />
<Route path="/lists/:id" component={ListDetail} />
<Route path="/friends/:id" component={FriendDetail} />
</div>
</BrowserRouter>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

in most SPA frameworks, you define routes up front

with React Router, routes are part of the component tree

so the routing happens as things are rendering

...

look - the router/route components are in the return statement

It's a subtle difference

But it allows you to write declarative routing

which is pretty easy to follow.

Routing

React Router

<BrowserRouter>

import { BrowserRouter, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" component={FriendsList} />
<Route path="/lists/:id" component={ListDetail} />
<Route path="/friends/:id" component={FriendDetail} />
</div>
</BrowserRouter>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

key components you'll use:

A Router that targets the browser

uses the HTML5 history API to keep your UI in sync with the URL.

you'll generally put this at the top of your app

Routing

React Router

<Route>

import { BrowserRouter, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" component={FriendsList} />
<Route path="/lists/:id" component={ListDetail} />
<Route path="/friends/:id" component={FriendDetail} />
</div>
</BrowserRouter>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

a few key arguments to a Route component

Routing

React Router

<Route>

path

<Route
path="/"
component={FriendsList}
exact
/>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • Which url is covered
  • can be static

Routing

React Router

<Route>

path

<Route
path="/"
component={FriendsList}
exact
/>
<Route
path="/lists/:id"
component={ListDetail}
/>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • Which url is covered
  • can be static
  • or can be dynamic, with arguments in it

Routing

React Router

<Route>

component

<Route
path="/lists/:id"
component={ListDetail}
/>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

which component handles this route?

Routing

React Router

<Route>

exact

<Route
path="/"
component={FriendsList}
exact
/>
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

does the path need to match exactly?

without this, the root path would always match.

...

That's all it takes to define your routes!

The other components you'll use from React-Router are for navigating

Routing

React Router

import { Link } from 'react-router-dom';
function FriendInList({ friend }) {
return <Link to={'/friends/' + friend.id}>{friend.name}</Link>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

effectively an anchor/href

Routing

React Router

import { NavLink } from 'react-router-dom';
function FriendInList({ friend }) {
return (
<header>
<NavLink to={'/'}>Home</NavLink>
<NavLink to={'/friends'}>Friends</NavLink>
<NavLink to={'/lists'}>Lists</NavLink>
</header>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • like a link, but it also sets an "active" class when it is selected.
  • useful in navigation where you want to identify current page

Exercise 8

React Router

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Routing

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Routing

Deeper Learning

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Routing

Deeper Learning

Transitions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

can use to:

  • block navigation (i.e. not authorized)
  • animate transitions

Routing

Deeper Learning

Reach Router

https://reach.tech/router

stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • written by co-author of react router
  • focused on accessibility

State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Who has heard things about managing state in react?

...

state mgmt in react is a controversial topic.

but it has gotten less controversial with more recent releases

State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

this is where we were

a component is a function of the props passed into it

State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

but that's not the only input to a component

a component is a function of props & state

...

distinction:

  • props are passed into a component

  • state is contained within a component

Think about it from a responsibility viewpoint

Who should be the source of truth for this data?

This component? It's state.

Someone else? It's props passed in.

State

State Is Passed Into Child Components As Props

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • top level manages state;
  • each component down the line passes it to the next

State

Hooks

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

To manage state, we'll use a new React feature named hooks

  • v16.8
  • new as of ~Feb 2019

State

Hooks

Hooks are functions you can use in a Component to perform impure actions from a pure function.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Remember we said our components are pure functions,

and pure functions shouldn't have side-effects, or change state

Hooks allow us to do that safely,

and in a way that allows React to re-render components when it needs to

State

Hooks

useState

useEffect

useReducer

useMemo

...

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Examples

  • manage state
  • perform side-effects
  • manage complicated state
  • memoize some data (another type of state)

All begin with "use" - allows React to identify hooks that you create

State

useState

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

our focus for state mgmt

useState

function FriendCounter() {
const state = useState(99);
const count = state[0];
const setCount = state[1];
return (
<div>
<h1>{count}</h1>
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • useState
  • initial value (99)
  • get an array back
  • first item in array = value
  • second item in array = state modifier

...

Why do we get back an array?

So we can do this:

useState

function FriendCounter() {
const [count, setCount] = useState(99);
return (
<div>
<h1>{count}</h1>
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • array destructuring
  • an array so that we can name them whatever we want

useState

function FriendCounter() {
const [count, setCount] = useState(99);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)} />
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

To use the state modifier,

We might add an onClick handler

  • when executed, calls setCount with the new value
  • fat-arrow because we pass onClick a function to execute
  • if we just called setCount() directly, that would happen at render instead of click

Exercise 9

Managing Component State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

build a component that uses state to manage which view is being shown

State

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

State

Suggestions

Only call hooks at the top level

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

That means never in a conditional or loop

  • Order of calls to useState matters
  • Hooks relies on order to keep track of each state prop - there's some magic

State

Suggestions

Elevate State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

State

Suggestions

Elevate State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

if I've got components down here that need the same state...

State

Suggestions

Elevate State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

I can elevate it to the nearest common ancestor

and manage the state there

State

Suggestions

Managing Many State Properties

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

You can call useState more than once

State

Suggestions

Many State Properties

function FriendForm() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
// ...
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Example: two state props, one for each name

State

Suggestions

Many State Properties

function FriendForm() {
const [firstName, setFirstName] = useState('');
const [middleInitial, setMiddleInitial] = useState('');
const [lastName, setLastName] = useState('');
const [nickname, setNickname] = useState('');
const [age, setAge] = useState(0);
// ...
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

But you can see how this can get out of hand, if you have a lot of form data

Here's 5 fields, maybe you even have more

...

There are a few ways to address this

State

Suggestions

Many State Properties

Custom Hook

function useFriendForm() {
const [firstName, setFirstName] = useState('');
// ...
return { firstName, middleInitial, ... }
}
function FriendForm() {
const form = useFriendForm();
// ...
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • Extract state mgmt to a custom hook
  • Return whatever would be useful to original component
  • Original component now uses custom hook
  • NOT Redux
  • But a reducer is a concept used by redux
  • good when state is complex

State

Suggestions

Many State Properties

External Library

Formik
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Or sometimes, using an external library might be an answer.

The one we use for managing form data is called Formik.

Side Effects

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Side effect = interacting with anything outside of React & your React components.

  • Data fetching
  • Subscribing to a websocket
  • and manually changing the DOM

Side Effects

useEffect

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Side Effects

useEffect

function Component(props) {
useEffect(
// arg 1: a function
() => {
A; // what to do when effect fires
return () => {
B; // what to do to clean up effect
}
},
// arg 2: an array
[ C ] // variables which should prompt effect to re-fire when changed
);
return ...
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

2 args, but 3 important things specified

  • nothing returned
  • A
  • B
  • C

Examples:

Side Effects

useEffect

Loading Data

import callApi from './callApi';
function DetailItem(props) {
const [item, setItem] = useState({});
useEffect(() => {
async function load() {
const item = await callApi(props.id);
setItem(item);
}
load();
}, []);
return ( ... )
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Loading data from an external source

  • callApi - an api client
  • useState - often, but not always associated with useEffect
  • async/await
    • useEffect can only return a function or nothing
    • so we can't mark the argument as async
  • first arg = what happens when the component mounts or the props change
  • no cleanup!
  • no props will cause it to re-fire - only fires once.

Side Effects

useEffect

Charting

function FriendsChart(props) {
useEffect(() => {
const graph = graphingLibrary.init(props.data);
return () => {
graph.destroy();
};
}, []);
return ( ... )
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Integrating with a charting library

  • init based on props
  • store graph
  • return function - destroy graph
  • no props should cause re-fire

Side Effects

useEffect

WebSockets

function Chat(props) {
useEffect(() => {
socket.emit('join', { id: props.friendId });
return () => {
socket.emit('leave', { id: props.friendId });
}
}, [ props.friendId ])
return ( ... )
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Integrating with websockets

  • join a socket when effect fires
  • leave that socket to clean up the effect
  • re-run the effect when props.friendId changes

Exercise 10

Loading Data

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

from an api

& rendering components based on the results

Side Effects

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Side Effects

Suggestions

You Can Run Multiple Effects

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Side Effects

Suggestions

Multiple Effects

function Component() {
useEffect(() => {
// Load Data
});
useEffect(() => {
// Charting
});
useEffect(() => {
// Websockets
});
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

If you have multiple things happening in an effect,

break them up into separate calls

No reason you can't do that

Each one will be run.

Advantage: easier to follow code

Application State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Application State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

app state is state that the entire app needs, or distant portions of it need.

...

if we're elevating state, this means we have to pass props basically through the entire app

this is called...

Application State

Prop Drilling

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

all this prop drilling can feel like a burden, and noisy

Application State

Context

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

and for app-level state, there's a fairly new api in react

new in React 16.3

Application State

Context

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

how context solves prop drilling

  • the top-most component will use the context as a "provider"

  • bottom components as "consumers"

  • anything under provider will have access to data from this context

  • w/o having to have props passed in

  • so props don't have to be drilled

Application State

Context

createContext()

const UserContext = React.createContext();
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

the first thing you have to do is create a context

this doesn't happen inside of a component

it's something that executes alongside your components

you get a provider & a consumer

  • like namespacing your context

Application State

Context

Provider

import UserContext from './user-context.js';
function UserProvider({ children }) {
const user = useUser(); // however you get the logged in user
return <UserContext.Provider value={user}>{children}</UserContext.Provider>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

-

the provider will get wrapped around your component tree

  • value = the data you want to pass to consumers
  • user = however you got the user - maybe via useEffect,...

Application State

Context

Provider

import UserContext from "./user-context.js"
function UserProvider({children}) {
const user = ... // however you get the logged in user
const handleUserChanged = ... // however you change the logged in user
return (
<UserContext.Provider
value={{
user: user,
onUserChanged: handleUserChanged,
}}
>
{children}
</UserContext.Provider>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

value can be an object, if there are multiple things you want to pass down

including actions that will change the value

Application State

Context

The Top Of Your Tree

import UserProvider from './user-provider.jsx';
function App() {
return (
<UserProvider>
<MyComponentTree />
</UserProvider>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Then this wrapped provider gets imported into App & rendered at the top of the tree

  • mycomponenttree will be the children of UserProvider

Application State

Context

Consumer

import React, { useContext } from 'react';
function UserName() {
const value = useContext(UserContext);
return <div>{value.user.name}</div>;
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

and then all the places in the subtree that you need access to the state, you have consumers

and they just want to know what the value of the context is

using a hook named useContext

Application State

Context

Consumer

function CurrentUser() {
const value = useContext(UserContext);
return (
<div>
Current User: {value.userName}
<button onClick={value.onUserChanged}>Change User</button>
</div>
);
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

for multiple things passed down via context...

  • note: not using fat-arrow for onClick because onUserChanged is a function already

Exercise 11

React Context

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Poll: on your own?

Or have me show you the code?

Application State

Deeper Learning

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Application State

Deeper Learning

Redux

Redux is a predictable state container for JavaScript apps.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

one store to hold all the data

and you connect your components to that state,

so that when it changes, your component re-renders.

Application State

Deeper Learning

Mobx

Simple, scalable state management

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

reactive programming, observables

updates get automatically applied

Application State

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Application State

Suggestions

Use The Right Tool

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Component state: use useState

Distant components: use context or Redux/mobx

Application State

Suggestions

Read The Hooks Docs

reactjs.org/docs/hooks-intro.html

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

we've looked at only three hooks; docs have:

  • explanation of motivation
  • rules of use
  • a ton of other hooks
  • custom hooks

Application State

Suggestions

react-use

streamich.github.io/react-use

stevenhicks.me/your-first-react-app 🦄 @pepopowitz
  • a ton of useful custom hooks

Legacy Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Prior to v16.8

Exercise 12

Modern JavaScript: Class Syntax

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Introduced recently

Used by legacy react components

Legacy Components

React.Component

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

legacy components are classes that extend React.Component.

Legacy Components

React.Component

import React from 'react';
class FriendDetail extends React.Component {
// ...Details about this component
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Legacy Components

render()

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

The only requirement for a react class component

is that it implements a render() function

  • comparable to the return value of a functional component

Legacy Components

render()

class FriendDetail extends React.Component {
render() {
return <div>...</div>;
}
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Note: class instance methods!

Legacy Components

Props

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Props are accessed differently

Legacy Components

Props

class FriendDetail extends React.Component {
render() {
return (
<div>
<h1>{this.props.name}</h1>
</div>
);
}
}
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

props are accessed on "this"

  • refers to the instance of the class that's being rendered

Exercise 13

Converting Components

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

10 minutes

convert between a modern & legacy component

Exercises 14 & 15

Legacy State Management & Side Effects

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

10 minutes

Legacy Components

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Legacy Components

Suggestions

Don't Rewrite Everything

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

Jest

Complete and ready to set-up JavaScript testing solution. Works out of the box for any React project.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

Jest

import aFunctionUnderTest from './a-function-under-test.js';
describe('A set of tests', () => {
it('does a certain thing', () => {
const result = aFunctionUnderTest();
expect(result).toEqual('a value');
});
});
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

describe

it

expect

Testing

Jest

Matchers (Assertions)

expect(a).toEqual(b);
expect(a).not.toEqual(b);
expect(a).toBeGreaterThan(b);
expect(a).toBeNull();
expect(a).toBeUndefined();
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

35 available, some are valid only against certain types

Testing

react-testing-library

Simple and complete React DOM testing utilities that encourage good testing practices.

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

...

there are 3 things you're going to do in a test using react-testing-library:

you're going to render your component

Testing

react-testing-library

2. Find Elements

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

find elements that were rendered

...

and find them the way a user would -

Testing

react-testing-library

2. Find Elements

const context = render(<FriendDetail ... />);
const loadingText = context.queryByText('Loading...');
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

find elements that were rendered

...

and find them the way a user would -

Testing

react-testing-library

2. Find Elements

const context = render(<FriendDetail ... />);
const loadingText = context.queryByText('Loading...');
const context = render(<FriendDetail ... />);
const friendImage = context.queryByAlt('Mr. Cat The Mystery Cat');
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

find elements that were rendered

...

and find them the way a user would -

Testing

react-testing-library

2. Find Elements

const context = render(<FriendDetail ... />);
const loadingText = context.queryByText('Loading...');
const context = render(<FriendDetail ... />);
const friendImage = context.queryByAlt('Mr. Cat The Mystery Cat');
const context = render(<FriendDetail ... />);
const loadingText = context.queryByTestId('friend-container');
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

find elements that were rendered

...

and find them the way a user would -

you might make assertions against what was rendered & found

  • like ex 1 exists
  • there's 2 of ex 2
  • ex 3 doesn't exist

Exercise 16

Testing Component Render

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

react-testing-library

3. Fire Events

import { render, fireEvent } from 'react-testing-library';
describe('...', () => {
it('...', () => {
const context = render(<FriendDetail ... />);
const button = context.queryByText('Details >');
fireEvent.click(button);
});
});
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

To test interactions of components,

you'll fire DOM events against the elements,

using fireEvent.

Exercise 17

Testing Component Interactions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

Deeper Learning

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

Deeper Learning

Enzyme

http://airbnb.io/enzyme/

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

enzyme does a LOT of stuff;

react-testing-library tries to keep the possibilities to things that users care about

Testing

Deeper Learning

Jest-DOM

https://github.com/gnapse/jest-dom

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

for more matchers that let you identify classes, attributes, things on DOM elements

Testing

Suggestions

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Testing

Suggestions

Async Helpers

it('shows details after clicking button', async () => {
const context = render(<FriendDetail />);
const button = context.getByText('Details');
fireEvent.click(button);
const details = await waitForElement(() =>
context.getByText('snuggles like a champion'));
// ...
});
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

specific to react-testing-library

async events are usually hard to test

but not with rtl

  • A: render
  • B: click a button
  • C: wait for an element to appear
  • D: make some assertion, ...

Testing

Suggestions

Async Helpers

async wait
async waitForElement
async waitForDomChange
stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Async helpers available

  • all wait 4500 ms by default

Testing

Suggestions

Extract Complexity & Logic

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

more general suggestions:

testing logic outside of components is easier than testing logic inside of components

Testing

Suggestions

Test What The User Experiences

Not Implementation

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Avoid testing for presence of css classes, unless it's the only way to prove something is working

Prefer testing presence of text elements

react-testing-library forces you to do this

Testing

Suggestions

Write "Unigration" Tests

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

unit tests are small

& people can be overly dogmatic about what defines a "unit"

integration tests are too slow

& we can tell a lot from our app without pulling in db/api's

Testing

Suggestions

Write "Unigration" Tests

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

somewhere in the middle of those is the "unigration" zone

if you're trying to test that component at the top of this subtree,

test component tree with all helper functions included

mock things that are slow/we don't own (api's)

Testing

Suggestions

Write Tests For Future You

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

You have all the context right now. You three months from now does not. Consider what they'll go through when they find a failing test! Make it easier for them to figure out.

Good Practices

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

create-react-app

bit.ly/create-react-app

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

problem solved: setting up webpack & react & other dependencies is difficult

spins up an app for us

sensible defaults

hides complexity of webpack, etc from us

if I were starting an app, I would use create-react-app.

Good Practices

Thinking In React

reactjs.org/docs/thinking-in-react.html

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

Thinking In React

Step 1: Break The UI Into A Component Hierarchy

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

Thinking In React

Step 1: Break The UI Into A Component Hierarchy

Step 2: Build A Static Version in React

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

Thinking In React

Step 1: Break The UI Into A Component Hierarchy

Step 2: Build A Static Version in React

Step 3: Identify The Minimal (but complete) Representation Of UI State

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

Thinking In React

Step 1: Break The UI Into A Component Hierarchy

Step 2: Build A Static Version in React

Step 3: Identify The Minimal (but complete) Representation Of UI State

Step 4: Identify Where Your State Should Live

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

Thinking In React

Step 1: Break The UI Into A Component Hierarchy

Step 2: Build A Static Version in React

Step 3: Identify The Minimal (but complete) Representation Of UI State

Step 4: Identify Where Your State Should Live

Step 5: Add Inverse Data Flow

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Good Practices

Isolate Complexity

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Try to make as many simple, dumb, functional components as possible

Push the complicated things & stateful things to the edges

This makes it easier to understand most of your app

Good Practices

Break Into Pieces

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

In general, this is a good strategy for problem-solving

It also is in regards to React

But it is ALSO a good strategy to make sure your components are small & easy to maintain.

Good Practices

Code That Changes Together Should Live Together

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

I mean this in a couple ways:

  1. our new way of looking at separation of concerns

markup + js + css

but also,

  1. when organizing code in your app

When grouped by file type, you have to bounce around to work on a feature

When grouped by feature, all you need is in one folder

Feedback

Green = Good; Yellow = Okay; Pink = Bad

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

I want to thank you for your time

I really appreciate it.

Survey

Questions after

Thank you!

Resources

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Images

stevenhicks.me/your-first-react-app 🦄 @pepopowitz

Setup

stevenhicks.me/your-first-react-app 🦄 @pepopowitz
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow