0% found this document useful (0 votes)
86 views

Full Stack React TOC

This document provides information about revising a book on React including updating the content on January 13th, 2020. It encourages joining the community Discord channel for support and lists ways to provide bug reports or get notified of updates. The document outlines how to best use the book, including running code examples, understanding code blocks and numbering. It provides information on setting up a development environment to work with the sample code including installing Node.js, npm and Git. The majority of the document consists of technical content for building React applications, including components, JSX, state management and refactoring code using Babel plugins.

Uploaded by

JPN
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
86 views

Full Stack React TOC

This document provides information about revising a book on React including updating the content on January 13th, 2020. It encourages joining the community Discord channel for support and lists ways to provide bug reports or get notified of updates. The document outlines how to best use the book, including running code examples, understanding code blocks and numbering. It provides information on setting up a development environment to work with the sample code including installing Node.js, npm and Git. The majority of the document consists of technical content for building React applications, including components, JSX, state management and refactoring code using Babel plugins.

Uploaded by

JPN
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Contents

Book Revision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Updated January 13th, 2020 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Join our Official Community Discord . . . . . . . . . . . . . . . . . . . . . . 1
Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Be notified of updates via Twitter . . . . . . . . . . . . . . . . . . . . . . . . . 1
We’d love to hear from you! . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

How to Get the Most Out of This Book . . . . . . . . . . . . . . . . . . . . . . . 1


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Running Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Project setups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Code Blocks and Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Code Block Numbering . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Emailing Us . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Get excited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Part I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Your first React Web Application . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Building Product Hunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Setting up your development environment . . . . . . . . . . . . . . . . . . . 9
Code editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Node.js and npm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Install Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
CONTENTS

Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Special instruction for Windows users . . . . . . . . . . . . . . . . . . . . . . 11
Ensure IIS is installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
JavaScript ES6/ES7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Sample Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Previewing the application . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Prepare the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
What’s a component? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Our first component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
JSX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
The developer console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Babel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
ReactDOM.render() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Building Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Making Product data-driven . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
The data model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Using props . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Rendering multiple products . . . . . . . . . . . . . . . . . . . . . . . . . 39
React the vote (your app’s first interaction) . . . . . . . . . . . . . . . . . . . 44
Propagating the event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Binding custom component methods . . . . . . . . . . . . . . . . . . . . 48
Using state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Setting state with this.setState() . . . . . . . . . . . . . . . . . . . . . 54
Updating state and immutability . . . . . . . . . . . . . . . . . . . . . . . . . 56
Refactoring with the Babel plugin transform-class-properties . . . . . . 63
Babel plugins and presets . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Property initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Refactoring Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Refactoring ProductList . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Congratulations! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
A time-logging app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Previewing the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
CONTENTS

Prepare the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72


Breaking the app into components . . . . . . . . . . . . . . . . . . . . . . . . 77
The steps for building React apps from scratch . . . . . . . . . . . . . . . . . 85
Step 2: Build a static version of the app . . . . . . . . . . . . . . . . . . . . . 87
TimersDashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
TimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
ToggleableTimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Render the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Step 3: Determine what should be stateful . . . . . . . . . . . . . . . . . . . . 96
State criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Applying the criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Step 4: Determine in which component each piece of state should live . . 98
The list of timers and properties of each timer . . . . . . . . . . . . . . 99
Whether or not the edit form of a timer is open . . . . . . . . . . . . . 99
Visibility of the create form . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Step 5: Hard-code initial states . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Adding state to TimersDashboard . . . . . . . . . . . . . . . . . . . . . . 100
Receiving props in EditableTimerList . . . . . . . . . . . . . . . . . . . 102
Props vs. state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Adding state to EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . 104
Timer remains stateless . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Adding state to ToggleableTimerForm . . . . . . . . . . . . . . . . . . . 105
Adding state to TimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Step 6: Add inverse data flow . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
TimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
ToggleableTimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
TimersDashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Updating timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Adding editability to Timer . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Updating EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Updating EditableTimerList . . . . . . . . . . . . . . . . . . . . . . . . . 120
Defining onEditFormSubmit() in TimersDashboard . . . . . . . . . . . 121
Deleting timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
CONTENTS

Adding the event handler to Timer . . . . . . . . . . . . . . . . . . . . . 124


Routing through EditableTimer . . . . . . . . . . . . . . . . . . . . . . . 125
Routing through EditableTimerList . . . . . . . . . . . . . . . . . . . . 126
Implementing the delete function in TimersDashboard . . . . . . . . . 127
Adding timing functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Adding a forceUpdate() interval to Timer . . . . . . . . . . . . . . . . . 129
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Add start and stop functionality . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Add timer action events to Timer . . . . . . . . . . . . . . . . . . . . . . 131
Create TimerActionButton . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Run the events through EditableTimer and EditableTimerList . . . 134
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Methodology review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

Components & Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
server.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
The Server API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
text/html endpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
JSON endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Playing with the API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Loading state from the server . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Fetch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Sending starts and stops to the server . . . . . . . . . . . . . . . . . . . . . . 156
Sending creates, updates, and deletes to the server . . . . . . . . . . . . . . . 159
Give it a spin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Next up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

JSX and the Virtual DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162


React Uses a Virtual DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Why Not Modify the Actual DOM? . . . . . . . . . . . . . . . . . . . . . . . . 162
What is a Virtual DOM? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Virtual DOM Pieces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
CONTENTS

ReactElement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Experimenting with ReactElement . . . . . . . . . . . . . . . . . . . . . 165
Rendering Our ReactElement . . . . . . . . . . . . . . . . . . . . . . . . . 167
Adding Text (with children) . . . . . . . . . . . . . . . . . . . . . . . . . 169
ReactDOM.render() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
JSX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
JSX Creates Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
JSX Attribute Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
JSX Conditional Child Expressions . . . . . . . . . . . . . . . . . . . . . 174
JSX Boolean Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
JSX Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
JSX Spread Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
JSX Gotchas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
JSX Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

Advanced Component Configuration with props, state, and children . . . 182


Intro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
How to use this chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Creating Components - ES6 Classes or Functional Components . . . . 184
render() Returns a ReactElement Tree . . . . . . . . . . . . . . . . . . . 185
Getting Data into render() . . . . . . . . . . . . . . . . . . . . . . . . . . 186
props are the parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
PropTypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Default props with getDefaultProps() . . . . . . . . . . . . . . . . . . . . . 190
Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Default value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Multiple contexts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Using state: Building a Custom Radio Button . . . . . . . . . . . . . . 196
Stateful components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
State updates that depend on the current state . . . . . . . . . . . . . . 205
Thinking About State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
Stateless Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Switching to Stateless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
CONTENTS

Stateless Encourages Reuse . . . . . . . . . . . . . . . . . . . . . . . . . . 212


Talking to Children Components with props.children . . . . . . . . . . . . 212
React.Children.map() & React.Children.forEach() . . . . . . . . . 215
React.Children.toArray() . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Forms 101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
The Basic Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Events and Event Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Back to the Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Text Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Accessing User Input With refs . . . . . . . . . . . . . . . . . . . . . . . 227
Using User Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Uncontrolled vs. Controlled Components . . . . . . . . . . . . . . . . . 233
Accessing User Input With state . . . . . . . . . . . . . . . . . . . . . . 234
Multiple Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
On Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Adding Validation to Our App . . . . . . . . . . . . . . . . . . . . . . . . 243
Creating the Field Component . . . . . . . . . . . . . . . . . . . . . . . . 248
Using our new Field Component . . . . . . . . . . . . . . . . . . . . . . . 252
Remote Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Building the Custom Component . . . . . . . . . . . . . . . . . . . . . . 260
Adding CourseSelect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Separation of View and State . . . . . . . . . . . . . . . . . . . . . . . . . 270
Async Persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Redux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Form Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Connect the Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Form Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
formsy-react . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
react-input-enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . 294
tcomb-form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
winterfell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
CONTENTS

react-redux-form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

Using Webpack with Create React App . . . . . . . . . . . . . . . . . . . . . . . 296


JavaScript modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Create React App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Exploring Create React App . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
public/index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
package.json . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
src/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
index.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Booting the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Webpack basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
Making modifications to the sample app . . . . . . . . . . . . . . . . . . . . . 318
Hot reloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Auto-reloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Creating a production build . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Ejecting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
Buckle up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Using Create React App with an API server . . . . . . . . . . . . . . . . . . . 328
The completed app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
How the app is organized . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
The server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Concurrently . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Using the Webpack development proxy . . . . . . . . . . . . . . . . . . 341
Webpack at large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
When to use Webpack/Create React App . . . . . . . . . . . . . . . . . 343

Unit Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345


Writing tests without a framework . . . . . . . . . . . . . . . . . . . . . . . . 345
Preparing Modash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Writing the first spec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
The assertEqual() function . . . . . . . . . . . . . . . . . . . . . . . . . 352
What is Jest? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Using Jest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
expect() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
CONTENTS

The first Jest test for Modash . . . . . . . . . . . . . . . . . . . . . . . . . 361


The other truncate() spec . . . . . . . . . . . . . . . . . . . . . . . . . . 363
The rest of the specs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Testing strategies for React applications . . . . . . . . . . . . . . . . . . . . . 366
Integration vs Unit Testing . . . . . . . . . . . . . . . . . . . . . . . . . . 366
Shallow rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Enzyme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
Testing a basic React component with Enzyme . . . . . . . . . . . . . . . . . 369
Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
The App component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
The first spec for App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
More assertions for App . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Using beforeEach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Simulating a change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Clearing the input field . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Simulating a form submission . . . . . . . . . . . . . . . . . . . . . . . . 396
Writing tests for the food lookup app . . . . . . . . . . . . . . . . . . . . . . . 405
FoodSearch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Exploring FoodSearch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Writing FoodSearch.test.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
In initial state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
A user has typed a value into the search field . . . . . . . . . . . . . . . 421
Mocking with Jest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Mocking Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
The API returns results . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
The user clicks on a food item . . . . . . . . . . . . . . . . . . . . . . . . 441
The API returns empty result set . . . . . . . . . . . . . . . . . . . . . . 447
Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452

Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
What’s in a URL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
React Router’s core components . . . . . . . . . . . . . . . . . . . . . . . 458
Building the components of react-router . . . . . . . . . . . . . . . . . . . 459
The completed app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459
Building Route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
Building Link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
CONTENTS

Building Router . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475


Building Redirect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
Using react-router . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
More Route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
Using Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
Dynamic routing with React Router . . . . . . . . . . . . . . . . . . . . . . . 496
The completed app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
The server’s API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
Starting point of the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Using URL params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Propagating pathnames as props . . . . . . . . . . . . . . . . . . . . . . . 517
Dynamic menu items with NavLink . . . . . . . . . . . . . . . . . . . . . 523
Supporting authenticated routes . . . . . . . . . . . . . . . . . . . . . . . . . . 527
The Client library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Implementing login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
PrivateRoute, a higher-order component . . . . . . . . . . . . . . . . . 537
Redirect state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544

Part II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Intro to Flux and Redux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Why Flux? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Flux is a Design Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
Flux overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
Flux implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
Redux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
Redux’s key ideas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
Building a counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
The counter’s actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
Incrementing the counter . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Decrementing the counter . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
CONTENTS

Supporting additional parameters on actions . . . . . . . . . . . . . . . 556


Building the store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
The core of Redux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Next up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
The beginnings of a chat app . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
Previewing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
Building the reducer() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
Initializing state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
Handling the ADD_MESSAGE action . . . . . . . . . . . . . . . . . . . . . . 569
Handling the DELETE_MESSAGE action . . . . . . . . . . . . . . . . . . . . 573
Subscribing to the store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
createStore() in full . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578
Connecting Redux to React . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
Using store.getState() . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Using store.subscribe() . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Using store.dispatch() . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
The app’s components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Preparing App.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
The App component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
The MessageInput component . . . . . . . . . . . . . . . . . . . . . . . . 586
The MessageView component . . . . . . . . . . . . . . . . . . . . . . . . . 588
Next up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590

Intermediate Redux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592


Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
Using createStore() from the redux library . . . . . . . . . . . . . . . . . . 594
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
Representing messages as objects in state . . . . . . . . . . . . . . . . . . . . 595
Updating ADD_MESSAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
Updating DELETE_MESSAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Updating the React components . . . . . . . . . . . . . . . . . . . . . . . 600
Introducing threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602
Supporting threads in initialState . . . . . . . . . . . . . . . . . . . . 604
CONTENTS

Supporting threads in the React components . . . . . . . . . . . . . . . 606


Modifying App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Turning MessageView into Thread . . . . . . . . . . . . . . . . . . . . . . 608
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609
Adding the ThreadTabs component . . . . . . . . . . . . . . . . . . . . . . . . 610
Updating App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 610
Creating ThreadTabs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
Supporting threads in the reducer . . . . . . . . . . . . . . . . . . . . . . . . . 613
Updating ADD_MESSAGE in the reducer . . . . . . . . . . . . . . . . . . . . 613
Updating the MessageInput component . . . . . . . . . . . . . . . . . . 620
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622
Updating DELETE_MESSAGE in the reducer . . . . . . . . . . . . . . . . . . 622
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Adding the action OPEN_THREAD . . . . . . . . . . . . . . . . . . . . . . . . . . 626
The action object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Modifying the reducer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Dispatching from ThreadTabs . . . . . . . . . . . . . . . . . . . . . . . . 628
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
Breaking up the reducer function . . . . . . . . . . . . . . . . . . . . . . . . . 630
A new reducer() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Updating threadsReducer() . . . . . . . . . . . . . . . . . . . . . . . . . 633
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
Adding messagesReducer() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
Modifying the ADD_MESSAGE action handler . . . . . . . . . . . . . . . . 639
Creating messagesReducer() . . . . . . . . . . . . . . . . . . . . . . . . . 640
Modifying the DELETE_MESSAGE action handler . . . . . . . . . . . . . . 641
Adding DELETE_MESSAGE to messagesReducer() . . . . . . . . . . . . . . 645
Defining the initial state in the reducers . . . . . . . . . . . . . . . . . . . . . 647
Initial state in reducer() . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
Adding initial state to activeThreadIdReducer() . . . . . . . . . . . . 648
Adding initial state to threadsReducer() . . . . . . . . . . . . . . . . . 649
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
Using combineReducers() from redux . . . . . . . . . . . . . . . . . . . . . . 651
Next up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652
CONTENTS

Using Presentational and Container Components with Redux . . . . . . . . 654


Presentational and container components . . . . . . . . . . . . . . . . . 654
Splitting up ThreadTabs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657
Splitting up Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663
Removing store from App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671
Generating containers with react-redux . . . . . . . . . . . . . . . . . . . . 672
The Provider component . . . . . . . . . . . . . . . . . . . . . . . . . . . 672
Wrapping App in Provider . . . . . . . . . . . . . . . . . . . . . . . . . . 673
Using connect() to generate ThreadTabs . . . . . . . . . . . . . . . . . . 674
Using connect() to generate ThreadDisplay . . . . . . . . . . . . . . . 678
Action creators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
Asynchronicity and server communication . . . . . . . . . . . . . . . . 690

Using GraphQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691


Your First GraphQL Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
GraphQL Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
GraphQL vs. REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695
GraphQL vs. SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696
Relay and GraphQL Frameworks . . . . . . . . . . . . . . . . . . . . . . . . . 697
Chapter Preview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698
Consuming GraphQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699
Exploring With GraphiQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699
GraphQL Syntax 101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
Complex Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710
Fragments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
Exploring a Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
Graph Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
Graph Connections and Edges . . . . . . . . . . . . . . . . . . . . . . . . . . . 720
Mutations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724
Subscriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725
GraphQL With JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727
CONTENTS

GraphQL With React . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728


Wrapping Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730

GraphQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731


Writing a GraphQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
Special setup for Windows users . . . . . . . . . . . . . . . . . . . . . . . . . 731
Game Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733
Express HTTP Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733
Adding First GraphQL Types . . . . . . . . . . . . . . . . . . . . . . . . . 736
Adding GraphiQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739
Introspection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741
Mutation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743
Rich Schemas and SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 746
Setting Up The Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 747
Schema Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 752
Object and Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754
Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761
Performance: Look-Ahead Optimizations . . . . . . . . . . . . . . . . . 764
Lists Continued . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767
Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 770
Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 780
Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 782
Rich Mutations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
Relay and GraphQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791
Performance: N+1 Queries . . . . . . . . . . . . . . . . . . . . . . . . . . 793
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 798

Relay Classic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799
What We’re Going to Cover . . . . . . . . . . . . . . . . . . . . . . . . . 800
What We’re Building . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801
Guide to the Code Structure . . . . . . . . . . . . . . . . . . . . . . . . . 805
Relay is a Data Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 807
Relay GraphQL Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808
Exploring Relay Conventions in GraphQL . . . . . . . . . . . . . . . . . 809
Fetching Objects By ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809
CONTENTS

Walking Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814


Changing Data with Mutations . . . . . . . . . . . . . . . . . . . . . . . 819
Relay GraphQL Queries Summary . . . . . . . . . . . . . . . . . . . . . 821
Adding Relay to Our App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
Quick Look at the Goal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
A Preview of the Author Page . . . . . . . . . . . . . . . . . . . . . . . . 824
Containers, Queries, and Fragments . . . . . . . . . . . . . . . . . . . . 825
Validating Our Relay Queries at Compile Time . . . . . . . . . . . . . . 826
Setting Up Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833
Adding Relay to Our Routes . . . . . . . . . . . . . . . . . . . . . . . . . 835
App Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836
AuthorQueries Component . . . . . . . . . . . . . . . . . . . . . . . . . . 838
AuthorPage Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839
Try It Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 840
AuthorPage with Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843
BooksPage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845
BooksPage Route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 846
BooksPage Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847
BooksPage render() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 850
BookItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851
BookItem Fragment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853
Fragment Value Masking . . . . . . . . . . . . . . . . . . . . . . . . . . . 853
Improving the AuthorPage . . . . . . . . . . . . . . . . . . . . . . . . . . 856
Changing Data With Mutations . . . . . . . . . . . . . . . . . . . . . . . . . . 859
Building a Book’s Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860
Book Page Editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 864
Mutations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867
Defining a Mutation Object . . . . . . . . . . . . . . . . . . . . . . . . . . 868
Inline Editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 873
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875
Where to Go From Here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 876

React Native . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877


Init . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 878
Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 880
<Navigator /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884
CONTENTS

renderScene() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 885
configureScene() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 888
Web components vs. Native components . . . . . . . . . . . . . . . . . . . . 891
<View /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892
<Text /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892
<Image /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893
<TextInput /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893
<TouchableHighlight />, <TouchableOpacity />, and <Touchable-
WithoutFeedback /> . . . . . . . . . . . . . . . . . . . . . . . 893
<ActivityIndicator /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 894
<WebView /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 894
<ScrollView /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 894
<ListView /> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 895
Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
StyleSheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 906
Flexbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908
HTTP requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
What is a promise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
Enter Promises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 933
Single-use guarantee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
Creating a promise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
Debugging with React Native . . . . . . . . . . . . . . . . . . . . . . . . . . . 937
Where to go from here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 939

Appendix A: PropTypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 941


Validators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942
string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943
number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944
boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 945
function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 946
object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 947
object shape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948
multiple types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 949
instanceOf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951
array of type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952
CONTENTS

node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 953
element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 954
any type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956
Optional & required props . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956
custom validator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957

Appendix B: ES6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960


Prefer const and let over var . . . . . . . . . . . . . . . . . . . . . . . . 960
Arrow functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961
Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 964
Object.assign() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967
Template literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968
The spread operator (...) . . . . . . . . . . . . . . . . . . . . . . . . . . . 969
Enhanced object literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 969
Default arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 970
Destructuring assignments . . . . . . . . . . . . . . . . . . . . . . . . . . 971

Appendix C: React Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 974


WARNING: Hooks are Alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . 974
Motivation behind Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 974
How Hooks Map to Component Classes . . . . . . . . . . . . . . . . . . . . . 975
Using Hooks Requires react "next" . . . . . . . . . . . . . . . . . . . . . . . 975
useState() Hook Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976
Our Component is a Function . . . . . . . . . . . . . . . . . . . . . . . . 979
Reading and Writing State . . . . . . . . . . . . . . . . . . . . . . . . . . 979
React Tracks the State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 980
Multiple States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 980
useEffect() Hook Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 981
Fetch Data and Update State . . . . . . . . . . . . . . . . . . . . . . . . . 983
Performance Concerns When Using Effects . . . . . . . . . . . . . . . . 983
useContext() Hook Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 984
The Point of Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 984
useContext() makes context easier to use . . . . . . . . . . . . . . . . . 984
Getting a Reference to the Context in a Larger App . . . . . . . . . . . 986
useRef() Hook Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
useRef() and forms with input . . . . . . . . . . . . . . . . . . . . . . . 987
CONTENTS

Using Custom Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 988


Writing Tests for React Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . 990
Writing tests for useState() Hook . . . . . . . . . . . . . . . . . . . . . . 991
Writing tests for useEffect() Hook . . . . . . . . . . . . . . . . . . . . . 992
Writing tests for useRef() Hook . . . . . . . . . . . . . . . . . . . . . . . 994
Community Reaction to Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . 995
References to the Different types of Hooks . . . . . . . . . . . . . . . . . . . 996
Future of Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997
More Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998

Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 999
Revision 40 - 2020-01-13 . . . . . . . . . . . . . . . . . . . . . . . . . . . 999
Revision 39 - 2019-01-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . 999
Revision 38 - 2018-12-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . 999
Revision 37 - 2018-12-19 . . . . . . . . . . . . . . . . . . . . . . . . . . . 999
Revision 36 - 2018-10-01 . . . . . . . . . . . . . . . . . . . . . . . . . . . 999
Revision 35 - 2018-04-02 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000
Revision 34 - 2017-10-17 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000
Revision 33 - 2017-08-31 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000
Revision 32 - 2017-06-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000
Revision 31 - 2017-05-18 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000
Revision 30 - 2017-04-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000
Revision 29 - 2017-04-13 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
Revision 28 - 2017-04-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
Revision 27 - 2017-03-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
Revision 26 - 2017-02-22 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
Revision 25 - 2017-02-17 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
Revision 24 - 2017-02-08 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
Revision 23 - 2017-02-06 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002
Revision 22 - 2017-02-01 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002
Revision 21 - 2017-01-27 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002
Revision 20 - 2017-01-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002
Revision 19 - 2016-12-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002
Revision 18 - 2016-11-22 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1003
Revision 17 - 2016-11-04 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1003
Revision 16 - 2016-10-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1003

You might also like