Fullstack React
The Complete Guide to ReactJS and Friends
Wri!en by Anthony Accomazzo, Ari Lerner, Nate Murray, Clay Allsopp, David
Gu!man, and Tyler McGinnis
Technical Advisor: Sophia Shoemaker
Contributors: Seulgi Kim
© 2017 Fullstack.io
All rights reserved. No portion of the book manuscript may be reproduced, stored in a retrieval
system, or transmi!ed in any form or by any means beyond the number of purchased copies,
except for a single backup or archival copy. "e code may be used freely in your projects,
commercial or otherwise.
"e authors and publisher have taken care in preparation of this book, but make no expressed
or implied warranty of any kind and assume no responsibility for errors or omissions. No
liability is assumed for incidental or consequential damagers in connection with or arising out
of the use of the information or programs container herein.
Typeset using Leanpub.
Published in San Francisco, California by Fullstack.io.
FULLSTACK
.io
Contents
Book Revision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chat With The Community! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Code Blocks and Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Code Block Numbering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Emailing Us . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Technical Support Response Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Get excited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Part I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Your first React Web Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Building Product Hunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Setting up your development environment . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Code editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Node.js and npm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Install Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Special instruction for Windows users . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Ensure IIS is installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
JavaScript ES6/ES7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Sample Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
CONTENTS
Previewing the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Prepare the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
What’s a component? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Our first component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
JSX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
The developer console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Babel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
ReactDOM.render() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Building
Product
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Making Product data-driven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
The data model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Using props . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Rendering multiple products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
React the vote (your app’s first interaction) . . . . . . . . . . . . . . . . . . . . . . . . . 37
Propagating the event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Binding custom component methods . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Using state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Setting state with this.setState() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Updating state and immutability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Refactoring with the Babel plugin transform-class-properties . . . . . . . . . . . . . 51
Babel plugins and presets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Property initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Refactoring Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Refactoring ProductList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Congratulations! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
A time-logging app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Previewing the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Prepare the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Breaking the app into components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
The steps for building React apps from scratch . . . . . . . . . . . . . . . . . . . . . . . . 69
Step 2: Build a static version of the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
TimersDashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
TimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
ToggleableTimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Render the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Step 3: Determine what should be stateful . . . . . . . . . . . . . . . . . . . . . . . . . . 79
State criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
CONTENTS
Applying the criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Step 4: Determine in which component each piece of state should live . . . . . . . . . . . 81
The list of timers and properties of each timer . . . . . . . . . . . . . . . . . . . . . . 82
Whether or not the edit form of a timer is open . . . . . . . . . . . . . . . . . . . . . 82
Visibility of the create form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Step 5: Hard-code initial states . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Adding state to TimersDashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Receiving props in EditableTimerList . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Props vs. state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Adding state to EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Timer remains stateless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Adding state to ToggleableTimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Adding state to TimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Step 6: Add inverse data flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
TimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
ToggleableTimerForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
TimersDashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Updating timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Adding editability to Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Updating EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Updating EditableTimerList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Defining onEditFormSubmit() in TimersDashboard . . . . . . . . . . . . . . . . . . . 99
Deleting timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Adding the event handler to Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Routing through EditableTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Routing through EditableTimerList . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Implementing the delete function in TimersDashboard . . . . . . . . . . . . . . . . . . 104
Adding timing functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Adding a forceUpdate() interval to Timer . . . . . . . . . . . . . . . . . . . . . . . . 106
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Add start and stop functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Add timer action events to Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Create TimerActionButton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Run the events through EditableTimer and EditableTimerList . . . . . . . . . . . . 109
Try it out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Methodology review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Components & Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
server.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
The Server API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
text/html endpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117