37,19 €
Build applications for web and native mobile platforms with React, JSX, Redux, and GraphQL
This books takes you through using React 16 and React Native 0.5 to create powerful and engaging desktop mobile and native applications for all platforms.
You start by learning how to craft composable UIs using React, ranging from rendering with JSX and creating reusable components to routing and creating isomorphic applications that run on Node.js.
We then move on to show you how to take the concepts of React and apply them to building Native UIs using React Native. You'll find out how to build responsive and streamlined UIs that can properly handle user interactions in a mobile environment. You'll also learn how to access device-specific APIs such as the Geolocation API, and how to handle offline development with React Native.
You will master handling application state, Unified Information Architecture, and using Flux, Redux, and Relay.
Towards the end of the book, you will learn how Flux ideas are encapsulated within React components using Relay and apply all the skills learned so far to create a React application that runs on every major platform.
This book is written for any JavaScript developer—beginner or expert—who wants to start learning how to put both of Facebook’s UI libraries to work. No knowledge of React is needed, though a working knowledge of ES2017 will help you follow along better.
Adam Boduch is a seasoned web application developer with a breadth of experience ranging from jQuery to React and everything in between. He is the author of over 10 books, including React Tooling and React Essentials.Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 467
Veröffentlichungsjahr: 2018
Copyright © 2018 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Kunal Chaudhari Acquisition Editor: Devanshi DoshiContent Development Editor: Onkar WaniTechnical Editor: Diksha WakodeCopy Editor: Safis EditingProject Coordinator:Sheejal ShahProofreader: Safis EditingIndexer: Aishwarya GangawaneProduction Coordinator: Arvindkumar Gupta
First published: March 2017 Second edition: September 2018
Production reference: 1260918
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78934-679-4
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Adam Boduch is a seasoned web application developer with a breadth of experience ranging from jQuery to React and everything in between. He is the author of over 10 books, including React Tooling and React Essentials.
Piotr Sroczkowski is a JavaScript developer, focused mainly on the backend with Node.js and NoSQL databases. He started amateur programming in 2009 and professional programming in 2014. In 2017, he graduated with an MSc in computer science from the Silesian University of Technology in Gliwice with a thesis entitled "Application of Heuristic Algorithms in Exploration of the Gene Mutations." As that title suggests, he's excited by heuristic algorithms and bioinformatics too. Beside his backend-focused job, in his free time, he’s interested in the web frontend with React and the mobile frontend with React Native. Moreover, one of his hobbies is data mining with JavaScript. Beside programming, he loves running long distances such as marathons and half-marathons.
Carlos Santana Roldan is a Senior Web Developer (frontend and backend); with more than 11 years of experience in the market. Currently he is working as a React Technical Lead in Disney ABC Television Group. He is the founder of Codejobs, one of the most popular Developers Communities in Latin America, training people in different web technologies such React, Node.js & JS (@codejobs).
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
React and React Native Second Edition
Packt Upsell
Why subscribe?
www.packt.com
Contributors
About the author
About the reviewer
Packt is searching for authors like you
Dedication
Preface
Who this book is for
What this book covers
Part I: React
Part II: React Native
Part III: React Architecture
To get the most out of this book
Download the example code files
Conventions used
Get in touch
Reviews
Why React?
What is React?
React is just the view
Simplicity is good
Declarative UI structure
Time and data
Performance matters
The right level of abstraction
What's new in React 16
Core architecture revamped
Lifecycle methods
Context API
Rendering fragments
Portals
Rendering lists and strings
Handling errors
Server-side rendering
Summary
Test your knowledge
Further reading
Rendering with JSX
What is JSX?
Hello JSX
Declarative UI structure
Just like HTML
Built-in HTML tags
HTML tag conventions
Describing UI structures
Creating your own JSX elements
Encapsulating HTML
Nested elements
Namespaced components
Using JavaScript expressions
Dynamic property values and text
Mapping collections to elements
Fragments of JSX
Wrapper elements
Avoiding unnecessary tags using fragments
Summary
Test your knowledge
Further reading
Component Properties, State, and Context
What is component state?
What are component properties?
Setting component state
Initial component state
Setting component state
Merging component state
Passing property values
Default property values
Setting property values
Stateless components
Pure functional components
Defaults in functional components
Container components
Providing and consuming context
Summary
Test your knowledge
Further reading
Event Handling, the React Way
Declaring event handlers
Declaring handler functions
Multiple event handlers
Importing generic handlers
Event handler context and parameters
Getting component data
Higher-order event handlers
Inline event handlers
Binding handlers to elements
Synthetic event objects
Event pooling
Summary
Test your knowledge
Further reading
Crafting Reusable Components
Reusable HTML elements
The difficulty with monolithic components
The JSX markup
Initial state and state helpers
Event handler implementation
Refactoring component structures
Start with the JSX
Implementing an article list component
Implementing an article item component
Implementing an add article component
Making components functional
Leveraging render props
Rendering component trees
Feature components and utility components
Summary
Test your knowledge 
Further Reading
The React Component Lifecycle
Why components need a lifecycle
Initializing properties and state
Fetching component data
Initializing state with properties
Updating state with properties
Optimize rendering efficiency
To render or not to render
Using metadata to optimize rendering
Rendering imperative components
Rendering jQuery UI widgets
Cleaning up after components
Cleaning up asynchronous calls
Containing errors with error boundaries
Summary
Test your knowledge
Further Reading
Validating Component Properties
Knowing what to expect
Promoting portable components
Simple property validators
Basic type validation
Requiring values
Any property value
Type and value validators
Things that can be rendered
Requiring specific types
Requiring specific values
Writing custom property validators
Summary
Test your knowledge
Further reading
Extending Components
Component inheritance
Inheriting state
Inheriting properties
Inheriting JSX and event handlers
Composition with higher-order components
Conditional component rendering
Providing data sources
Summary
Test your knowledge
Further reading
Handling Navigation with Routes
Declaring routes
Hello route
Decoupling route declarations
Parent and child routes
Handling route parameters
Resource IDs in routes
Optional parameters
Using link components
Basic linking
URL and query parameters
Summary
Test your knowledge
Further reading
Server-Side React Components
What is isomorphic JavaScript?
The server is a render target
Initial load performance
Sharing code between the server and the browser
Rendering to strings
Backend routing
Frontend reconciliation
Fetching data
Summary
Test your knowledege
Further reading
Mobile-First React Components
The rationale behind mobile-first design
Using react-bootstrap components
Implementing navigation
Lists
Forms
Summary
Test your knowledge
Further reading
Why React Native?
What is React Native?
React and JSX are familiar
The mobile browser experience
Android and iOS, different yet the same
The case for mobile web apps
Summary
Test your knowledge
Further reading
Kickstarting React Native Projects
Installing and using the create-react-native-app
Creating a React Native app
Running your app
Installing and using Expo
Using simulators
iOS simulators
Android simulators
Summary
Test your knowledge
Further reading
Building Responsive Layouts with Flexbox
Flexbox is the new layout standard
Introducing React Native styles
Building flexbox layouts
Simple three column layout
Improved three column layout
Flexible rows
Flexible grids
Flexible rows and columns
Summary
Test your knowledge
Further reading
Navigating Between Screens
Navigation basics
Route parameters
The navigation header
Tab and drawer navigation
Handling state
Summary
Test your knowledege
Further reading
Rendering Item Lists
Rendering data collections
Sorting and filtering lists
Fetching list data
Lazy list loading
Summary
Test your knowledege
Further reading
Showing Progress
Progress and usability
Indicating progress
Measuring progress
Navigation indicators
Step progress
Summary
Test your knowledge
Further reading
Geolocation and Maps
Where am I?
What's around me?
Annotating points of interest
Plotting points
Plotting overlays
Summary
Test your knowledge
Further reading
Collecting User Input
Collecting text input
Selecting from a list of options
Toggling between off and on
Collecting date/time input
Summary
Test your knowledge
Further reading
Alerts, Notifications, and Confirmation
Important information
Getting user confirmation
Success confirmation
Error confirmation
Passive notifications
Activity modals
Summary
Test your knowledge
Further reading
Responding to User Gestures
Scrolling with your fingers
Giving touch feedback
Swipeable and cancellable
Summary
Test your knowledge
Further reading
Controlling Image Display
Loading images
Resizing images
Lazy image loading
Rendering icons
Summary
Test your knowledge
Further reading
Going Offline
Detecting the state of the network
Storing application data
Synchronizing application data
Summary
Test your knowledge
Further reading
Handling Application State
Information architecture and Flux
Unidirectionality
Synchronous update rounds
Predictable state transformations
Unified information architecture
Implementing Redux
Initial application state
Creating the store
Store provider and routes
The App component
The Home component
State in mobile apps
Scaling the architecture
Summary
Test your knowledge
Further reading
Why Relay and GraphQL?
Yet another approach?
Verbose vernacular
Declarative data dependencies
Mutating application state
The GraphQL backend and microservices
Summary
Test your knowledge
Further reading
Building a Relay React App
TodoMVC and Relay
The GraphQL schema
Bootstrapping Relay
Adding todo items
Rendering todo items
Completing todo items
Summary
Test Your Knowledge Answers
Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5
Chapter 6 
Chapter 7
Chapter 8
Chapter 9
Chapter 10
Chapter 11
Chapter 12
Chapter 13
Chapter 14
Chapter 15
Chapter 16
Chapter 17
Chapter 18
Chapter 19
Chapter 20
Chapter 21
Chapter 22
Chapter 23
Chapter 24
Chapter 25
Other Books You May Enjoy
Leave a review - let other readers know what you think
I never had any interest in developing mobile apps. I used to believe strongly that it was the web, or nothing, that there was no need for more yet more applications to install on devices that are already overflowing with apps. Then React Native happened. I was already writing React code for web applications and loving it. It turns out that I wasn’t the only developer that balked at the idea of maintaining several versions of the same app using different tooling, environments, and programming languages. React Native was created out of a natural desire to take what works well from a web development experience standpoint (React), and apply it to native app development. Native mobile apps offer better user experiences than web browsers. It turns out I was wrong, we do need mobile apps for the time being. But that’s okay, because React Native is a fantastic tool. This book is essentially my experience as a React developer for the web and as a less experienced mobile app developer. React Native is meant to be an easy transition for developers who already understand React for the Web. With this book, you’ll learn the subtleties of doing React development in both environments. You’ll also learn the conceptual theme of React, a simple rendering abstraction that can target anything. Today, it’s web browsers and mobile devices. Tomorrow, it could be anything.
The second edition of this book was written to address the rapidly evolving React project - including the state-of-the-art best practices for implementing React components as well as the ecosystem surrounding React. I think it's important for React developers to appreciate how React works and how the implementation of React changes to better support the people who rely on it. I've done my best to capture the essence of React as it is today and the direction it's moving, in this edition of React and React Native.
This book is written for any JavaScript developer—beginner or expert—who wants to start learning how to put both of Facebook’s UI libraries to work. No knowledge of React is needed, though a working knowledge of ES2017 will help you follow along better.
This book covers the following three parts:
React: Chapter 1 to 11
React Native:
Chapter 12 to 23
React Architecture: Chapter 23 to 26
Chapter 1, Why React?, covers the basics of what React really is, and why you want to use it.
Chapter 2, Rendering with JSX, explains that JSX is the syntax used by React to render content. HTML is the most common output, but JSX can be used to render many things, such as native UI components.
Chapter 3, Component Properties, State, and Context, shows how properties are passed to components, how state re-renders components when it changes, and the role of context in components.
Chapter 4, Event Handling—The React Way, explains that events in React are specified in JSX. There are subtleties with how React processes events, and how your code should respond to them.
Chapter 5, Crafting Reusable Components, shows that components are often composed using smaller components. This means that you have to properly pass data and behavior to child components.
Chapter 6, The React Component Lifecycle, explains how React components are created and destroyed all the time. There are several other lifecycle events that take place in between where you do things such as fetch data from the network.
Chapter 7, Validating Component Properties, shows that React has a mechanism that allows you to validate the types of properties that are passed to components. This ensures that there are no unexpected values passed to your component.
Chapter 8, Extending Components, provides an introduction to the mechanisms used to extend React components. These include inheritance and higher-order components.
Chapter 9, Handling Navigation with Routes, explains that navigation is an essential part of any web application. React handles routes declaratively using the react-router package.
Chapter 10, Server-Side React Components, discusses how React renders components to the DOM when rendered in the browser. It can also render components to strings, which is useful for rendering pages on the server and sending static content to the browser.
Chapter 11, Mobile-First React Components, explains that mobile web applications are fundamentally different from web applications designed for desktop screen resolutions. The react-bootstrap package can be used to build UIs in a mobile-first fashion.
Chapter 12, Why React Native?, shows that React Native is React for mobile apps. If you’ve already invested in React for web applications, then why not leverage the same technology to provide a better mobile experience?
Chapter 13, Kickstarting React Native Projects, discusses that nobody likes writing boilerplate code or setting up project directories. React Native has tools to automate these mundane tasks.
Chapter 14, Building Responsive Layouts with Flexbox, explains why the Flexbox layout model is popular with web UI layouts using CSS. React Native uses the same mechanism to layout screens.
Chapter 15, Navigating Between Screens, discusses the fact that while navigation is an important part of web applications, mobile applications also need tools to handle how a user moves from screen to screen.
Chapter 16, Rendering Item Lists, shows that React Native has a list view component that’s perfect for rendering lists of items. You simply provide it with a data source, and it handles the rest.
Chapter 17, Showing Progress, explains that progress bars are great for showing a determinate amount of progress. When you don’t know how long something will take, you use a progress indicator. React Native has both of these components.
Chapter 18, Geolocation and Maps, shows that the react-native-maps package provides React Native with mapping capabilities. The Geolocation API that’s used in web applications is provided directly by React Native.
Chapter 19, Collecting User Input, shows that most applications need to collect input from the user. Mobile applications are no different, and React Native provides a variety of controls that are not unlike HTML form elements.
Chapter 20, Alerts, Notifications, and Confirmation, explains that alerts are for interrupting the user to let them know something important has happened, notifications are unobtrusive updates, and confirmation is used for getting an immediate answer.
Chapter 21, Responding to User Gestures, discusses how gestures on mobile devices are something that’s difficult to get right in the browser. Native apps, on the other hand, provide a much better experience for swiping, touching, and so on. React Native handles a lot of the details for you.
Chapter 22, Controlling Image Display, shows how images play a big role in most applications, either as icons, logos, or photographs of things. React Native has tools for loading images, scaling them, and placing them appropriately.
Chapter 23, Going Offline, explains that mobile devices tend to have volatile network connectivity. Therefore, mobile apps need to be able to handle temporary offline conditions. For this, React Native has local storage APIs.
Chapter 24, Handling Application State, discusses how application state is important for any React application, web or mobile. This is why understanding libraries such as Redux and Immutable.js is important.
Chapter 25, Why Relay and GraphQL?, explains that Relay and GraphQL, used together, is a novel approach to handling state at scale. It’s a query and mutation language, plus a library for wrapping React components.
Chapter 26, Building a Relay React App, shows that the real advantage of Relay and GraphQL is that your state schema is shared between web and native versions of your application.
Inform the reader of the things that they need to know before they start, and spell out what knowledge you are assuming.
Any additional installation instructions and information they need for getting set up.
A code editor
A modern web browser
NodeJS
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/React-and-React-Native-Second-Edition. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "Mount the downloaded WebStorm-10*.dmg disk image file as another disk in your system."
A block of code is set as follows:
import React, { Component } from 'react';// Renders a "<button>" element, using// "this.props.children" as the text.export default class MyButton extends Component { render() { return <button>{this.props.children}</button>; }}
Any command-line input or output is written as follows:
$
npm install -g create-react-native-app
$
create-react-native-app my-project
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Select System info from the Administration panel."
Feedback from our readers is always welcome.
General feedback: Email [email protected] and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
If you're reading this book, you might already have some idea of what React is. You also might have heard a React success story or two. If not, don't worry. I'll do my best to spare you from additional marketing literature in this opening chapter. However, this is a large book, with a lot of content, so I feel that setting the tone is an appropriate first step. Yes, the goal is to learn React and React Native. But, it's also to put together a lasting architecture that can handle everything we want to build with React today, and in the future.
This chapter starts with a brief explanation of why React exists. Then, we'll talk about the simplicity that makes React an appealing technology and how React is able to handle many of the typical performance issues faced by web developers. Next, we'll go over the declarative philosophy of React and the level of abstraction that React programmers can expect to work with. Finally, we'll touch on some of the major new features of React 16.
Let's go!
I think the one-line description of React on its home page (https://facebook.github.io/react) is brilliant:
It's a library for building user interfaces. This is perfect because as it turns out, this is all we want most of the time. I think the best part about this description is everything that it leaves out. It's not a mega framework. It's not a full-stack solution that's going to handle everything from the database to real-time updates over web socket connections. We don't actually want most of these pre-packaged solutions, because in the end, they usually cause more problems than they solve.
React is generally thought of as the view layer in an application. You might have used a library such as Handlebars or jQuery in the past. Just like jQuery manipulates UI elements, or Handlebars templates are inserted onto the page, React components change what the user sees. The following diagram illustrates where React fits in our frontend code:
This is literally all there is to React—the core concept. Of course there will be subtle variations to this theme as we make our way through the book, but the flow is more or less the same. We have some application logic that generates some data. We want to render this data to the UI, so we pass it to a React component, which handles the job of getting the HTML into the page.
You may wonder what the big deal is, especially since at the surface, React appears to be yet another rendering technology. We'll touch on some of the key areas where React can simplify application development in the remaining sections of the chapter.
React doesn't have many moving parts to learn about and understand. Internally, there's a lot going on, and we'll touch on these things here and there throughout the book. The advantage to having a small API to work with is that you can spend more time familiarizing yourself with it, experimenting with it, and so on. The opposite is true of large frameworks, where all your time is devoted to figuring out how everything works. The following diagram gives a rough idea of the APIs that we have to think about when programming with React:
React is divided into two major APIs. First, there's the React DOM. This is the API that's used to perform the actual rendering on a web page. Second, there's the React component API. These are the parts of the page that are actually rendered by React DOM. Within a React component, we have the following areas to think about:
Data
: This is data that comes from somewhere (the component doesn't care where), and is rendered by the component.
Lifecycle
: These are methods that we implement that respond to changes in the lifecycle of the component. For example, the component is about to be rendered.
Events
: This is code that we write for responding to user interactions.
JSX
: This is the syntax of React components used to describe UI structures.
Don't fixate on what these different areas of the React API represent just yet. The takeaway here is that React, by nature, is simple. Just look at how little there is to figure out! This means that we don't have to spend a ton of time going through API details here. Instead, once you pick up on the basics, we can spend more time on nuanced React usage patterns.
React newcomers have a hard time coming to grips with the idea that components mix markup in with their JavaScript. If you've looked at React examples and had the same adverse reaction, don't worry. Initially, we're all skeptical of this approach, and I think the reason is that we've been conditioned for decades by the separation of concerns principle. Now, whenever we see things mixed together, we automatically assume that this is bad and shouldn't happen.
The syntax used by React components is called JSX (JavaScript XML). A component renders content by returning some JSX. The JSX itself is usually HTML markup, mixed with custom tags for the React components. The specifics don't matter at this point; we'll get into details in the coming chapters. What's absolutely groundbreaking here is that we don't have to perform little micro-operations to change the content of a component.
For example, think about using something like jQuery to build your application. You have a page with some content on it, and you want to add a class to a paragraph when a button is clicked. Performing these steps is easy enough. This is called imperative programming, and it's problematic for UI development. While this example of changing the class of an element in response to an event is simple, real applications tend to involve more than three or four steps to make something happen.
React components don't require executing steps in an imperative way to render content. This is why JSX is so central to React components. The XML-style syntax makes it easy to describe what the UI should look like. That is, what are the HTML elements that this component is going to render? This is called declarative programming, and is very well suited for UI development.
Another area that's difficult for React newcomers to grasp is the idea that JSX is like a static string, representing a chunk of rendered output. This is where time and data come into play. React components rely on data being passed into them. This data represents the dynamic aspects of the UI. For example, a UI element that's rendered based on a Boolean value could change the next time the component is rendered. Here's an illustration of the idea:
Each time the React component is rendered, it's like taking a snapshot of the JSX at that exact moment in time. As your application moves forward through time, you have an ordered collection of rendered user interface components. In addition to declaratively describing what a UI should be, re-rendering the same JSX content makes things much easier for developers. The challenge is making sure that React can handle the performance demands of this approach.
Using React to build user interfaces means that we can declare the structure of the UI with JSX. This is less error-prone than the imperative approach to assembling the UI piece by piece. However, the declarative approach does present us with one challenge: performance.
For example, having a declarative UI structure is fine for the initial rendering, because there's nothing on the page yet. So, the React renderer can look at the structure declared in JSX, and render it into the DOM browser.
This concept is illustrated in the following diagram:
On the initial render, React components and their JSX are no different from other template libraries. For instance, Handlebars will render a template to HTML markup as a string, which is then inserted into the browser DOM. Where React is different from libraries such as Handlebars is when data changes and we need to re-render the component. Handlebars will just rebuild the entire HTML string, the same way it did on the initial render. Since this is problematic for performance, we often end up implementing imperative workarounds that manually update tiny bits of the DOM. We end up with a tangled mess of declarative templates and imperative code to handle the dynamic aspects of the UI.
We don't do this in React. This is what sets React apart from other view libraries. Components are declarative for the initial render, and they stay this way even as they're re-rendered. It's what React does under the hood that makes re-rendering declarative UI structures possible.
React has something called the virtual DOM, which is used to keep a representation of the real DOM elements in memory. It does this so that each time we re-render a component, it can compare the new content to the content that's already displayed on the page. Based on the difference, the virtual DOM can execute the imperative steps necessary to make the changes. So not only do we get to keep our declarative code when we need to update the UI, React will also make sure that it's done in a performant way. Here's what this process looks like:
Like any other JavaScript library, React is constrained by the run-to-completion nature of the main thread. For example, if the React internals are busy diffing content and patching the DOM, the browser can't respond to user input. As you'll see in the last section of this chapter, changes were made to the internal rendering algorithms in React 16 to mitigate these performance pitfalls.
Another topic I want to cover at a high level before we dive into React code is abstraction. React doesn't have a lot of it, and yet the abstractions that React implements are crucial to its success.
In the preceding section, you saw how JSX syntax translates to low-level operations that we have no interest in maintaining. The more important way to look at how React translates our declarative UI components is the fact that we don't necessarily care what the render target is. The render target happens to be the browser DOM with React, but it isn't restricted to the browser DOM.
React has the potential to be used for any user interface we want to create, on any conceivable device. We're only just starting to see this with React Native, but the possibilities are endless. I personally will not be surprised when React Toast becomes a thing, targeting toasters that can singe the rendered output of JSX on to bread. The abstraction level with React is at the right level, and it's in the right place.
The following diagram gives you an idea of how React can target more than just the browser:
From left to right, we have React Web (just plain React), React Native, React Desktop, and React Toast. As you can see, to target something new, the same pattern applies:
Implement components specific to the target
Implement a React renderer that can perform the platform-specific operations under the hood
Profit
This is obviously an oversimplification of what's actually implemented for any given React environment. But the details aren't so important to us. What's important is that we can use our React knowledge to focus on describing the structure of our user interface on any platform.
In this section, I want to highlight the major changes and the new features of React 16. I'll go into more detail about the given changes as we encounter them in the subsequent chapters throughout the book.
Perhaps the biggest change in React 16 is to the internal reconciliation code. These changes don't impact the way that you interact with the React API. Instead, these changes were made to address some pain points that were preventing React from scaling up in certain situations. For example, one of the main concepts from this new architecture is that of a fiber. Instead of rendering every component on the page in a run-to-compilation way, React renders fibers—smaller chunks of the page that can be prioritized and rendered asynchronously.
For a more in depth look at this new architecture, these resources should be helpful:
https://github.com/acdlite/react-fiber-architecture
https://reactjs.org/blog/2017/09/26/react-v16.0.html
React 16 had to revamp some of the lifecycle methods that are available to class components. Some lifecycle methods are deprecated and will eventually be removed. There are new lifecycle methods to replace them. The main issue is that the deprecated lifecycle methods encourage coding in ways that doesn't work well with the new async React core.
For more on these lifecycle methods, visit this page: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.
React has always provided a context API for developers, but it was always considered experimental. Context is an alternative approach to passing data from one component to the next. For example, using properties, you can pass data through a tree of components that is several layers deep. The components in the middle of this tree don't actually use any of these properties—they're just acting as intermediaries. This becomes problematic as your application grows because you have lots of props in your source that add to the complexity.
The new context API in React 16.3 is more official and provides a way for you to supply your components with data at any tree level. You can read more about the new context API here: https://reactjs.org/docs/context.html.
If your React component renders several sibling elements, say three <p> elements for instance, you would have to wrap them in a <div> because React would only allow components to return a single element. The only problem with this approach is that it leads to a lot of unnecessary DOM structure. Wrapping your elements with <Fragment> is the same idea as wrapping them with a <div>, except there won't be any superfluous DOM elements.
You can read more about fragments here: https://reactjs.org/docs/fragments.html.
When a React component returns content, it gets rendered into its parent component. Then, that parent's content gets rendered into its parent component and so on, all the way to the tree root. There are times when you want to render something that specifically targets a DOM element. For example, a component that should be rendered as a dialog probably doesn't need to be mounted at the parent. Using a portal, you can control specifically where your component's content is rendered.
You can read more about portals here: https://reactjs.org/docs/portals.html.
Prior to React 16, components had to return either an HTML element or another React component as its content. This can restrict how you compose your application. For example, you might have a component that is responsible for generating an error message. You used to have to wrap these strings in HTML tags in order to be considered valid React component output. Now you can just return the string. Similarly, you can just return a list of strings or a list of elements.
The blog post introducing React 16 has more details on this new functionality: https://reactjs.org/blog/2017/09/26/react-v16.0.html.
Error handling in React can be difficult. Where exactly do you handle errors? If a component handles a JavaScript exception and sets an error state on the component to true, how do you reset this state? In React 16, there are error boundaries. Error boundaries are created by implementing the componentDidCatch() lifecycle method in a component. This component can then serve as the error boundary by wrapping other components. If any of the wrapped components throws an exception, the error boundary component can render alternative content.
Having error boundaries in place like this allows you to structure your components in a way that best suits your application. You can read more about error boundaries here: https://reactjs.org/docs/error-boundaries.html.
Server-side rendering (SSR) in React can be difficult to wrap your head around. You're rendering on the server, then rendering on the client too? Since the SSR pattern has become more prevalent, the React team has made it easier to work with in React 16. In addition, there are a number of internal performance gains as well as efficiency gains by enabling streaming rendered content to the client.
If you want to read more about SSR in React 16, I recommend the following resources:
https://hackernoon.com/whats-new-with-server-side-rendering-in-react-16-9b0d78585d67
https://reactjs.org/docs/react-dom-server.html
In this chapter, you were introduced to React at a high level. React is a library, with a small API, used to build user interfaces. Next, you were introduced to some of the key concepts of React. First, we discussed the fact that React is simple, because it doesn't have a lot of moving parts. Next, we looked at the declarative nature of React components and JSX. Then, you learned that React takes performance seriously, and that this is how we're able to write declarative code that can be re-rendered over and over. Next, you learned about the idea of render targets and how React can easily become the UI tool of choice for all of them. Lastly, I gave a rough overview of what's new in React 16.
That's enough introductory and conceptual stuff for now. As we make our way toward the end of the book, we'll revisit these ideas. For now, let's take a step back and nail down the basics, starting with JSX.
What is a declarative UI structure and how does React support this idea?
A declarative UI is built from components that are all declared before they're used. React will fail to render if all components aren't declared upfront.
Declarative UI structures define what the UI component is instead of worrying about how it is defined. React supports this idea by allowing components to be declared using JSX syntax.
Declarative UI structures are entirely optional in React. You can just as easily follow an imperative approach.
How does React improve rendering performance?
React has a virtual DOM that compares changes made to components' data in memory, avoiding the browser DOM when possible. React 16 has a new internal architecture that allows rendering to be split up into smaller chunks of work and prioritized.
React sets up web workers so that whenever possible, work is parallelized.
React doesn't focus on performance, instead relying on incremental browser performance improvements.
When would you render a fragment?
Fragments are used when you need a placeholder in your rendered content.
Fragments are used to improve the performance of its child elements.
Fragments are used to avoid having to render unnecessary DOM elements.
Take a look at the following links for more information:
https://facebook.github.io/react
https://github.com/acdlite/react-fiber-architecture
https://reactjs.org/blog/2017/09/26/react-v16.0.html
https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html
https://reactjs.org/docs/context.html
https://reactjs.org/docs/fragments.html
https://reactjs.org/docs/portals.html
https://reactjs.org/blog/2017/09/26/react-v16.0.html
https://reactjs.org/docs/error-boundaries.html
https://hackernoon.com/whats-new-with-server-side-rendering-in-react-16-9b0d78585d67
https://reactjs.org/docs/react-dom-server.html
https://github.com/facebook/react/wiki/Sites-Using-React
This chapter will introduce you to JSX. We'll start by covering the basics: what is JSX? Then, you'll see that JSX has built-in support for HTML tags, as you would expect, so we'll run through a few examples here. After having looked at some JSX code, we'll discuss how it makes describing the structure of UIs easy for us. Then, we'll jump into building our own JSX elements, and using JavaScript expressions for dynamic content. Finally, you'll learn how to use fragments to produce less HTML—a new React 16 feature.
Ready?
In this section, we'll implement the obligatory hello world JSX application. At this point, we're just dipping our toes into the water; more in-depth examples will follow. We'll also discuss what makes this syntax work well for declarative UI structures.
Without further ado, here's your first JSX application:
// The "render()" function will render JSX markup and// place the resulting content into a DOM node. The "React"// object isn't explicitly used here, but it's used// by the transpiled JSX source.import React from 'react';import { render } from 'react-dom';// Renders the JSX markup. Notice the XML syntax// mixed with JavaScript? This is replaced by the// transpiler before it reaches the browser.render( <p> Hello, <strong>JSX</strong> </p>, document.getElementById('root'));
Let's walk through what's happening here. First, we need to import the relevant bits. The render() function is what really matters in this example, as it takes JSX as the first argument and renders it to the DOM node passed as the second argument.
The actual JSX content in this example renders a paragraph with some bold text inside. There's nothing fancy going on here, so we could have just inserted this markup into the DOM directly as a plain string. However, there's a lot more to JSX than what's shown here. The aim of this example was to show the basic steps involved in getting JSX rendered onto the page. Now, let's talk a little bit about declarative UI structure.
Before we continue forward with our code examples, let's take a moment to reflect on our hello world example. The JSX content was short and simple. It was also declarative, because it described what to render, not how to render it. Specifically, by looking at the JSX, you can see that this component will render a paragraph, and some bold text within it. If this were done imperatively, there would probably be some more steps involved, and they would probably need to be performed in a specific order.
The example we just implemented should give you a feel for what declarative React is all about. As we move forward in this chapter and throughout the book, the JSX markup will grow more elaborate. However, it's always going to describe what is in the user interface. Let's move on.
At the end of the day, the job of a React component is to render HTML into the DOM browser. This is why JSX has support for HTML tags, out of the box. In this section, we'll look at some code that renders a few of the available HTML tags. Then, we'll cover some of the conventions that are typically followed in React projects when HTML tags are used.
When we render JSX, element tags are referencing React components. Since it would be tedious to have to create components for HTML elements, React comes with HTML components. We can render any HTML tag in our JSX, and the output will be just as we'd expect. Now, let's try rendering some of these tags:
import React from 'react';import { render } from 'react-dom';// The render() function will only complain if the browser doesn't// recognize the tagrender( <div> <button /> <code /> <input /> <label /> <p /> <pre /> <select /> <table /> <ul /> </div>, document.getElementById('root'));
Don't worry about the rendered output for this example; it doesn't make sense. All we're doing here is making sure that we can render arbitrary HTML tags, and they render as expected.
When you render HTML tags in JSX markup, the expectation is that you'll use lowercase for the tag name. In fact, capitalizing the name of an HTML tag will fail. Tag names are case sensitive and non-HTML elements are capitalized. This way, it's easy to scan the markup and spot the built-in HTML elements versus everything else.
You can also pass HTML elements any of their standard properties. When you pass them something unexpected, a warning about the unknown property is logged. Here's an example that illustrates these ideas:
import React from 'react';import { render } from 'react-dom';// This renders as expected, except for the "foo"// property, since this is not a recognized button// property.render( <button title="My Button" foo="bar"> My Button </button>, document.getElementById('root'));// This fails with a "ReferenceError", because// tag names are case-sensitive. This goes against// the convention of using lower-case for HTML tag names.render(<Button />, document.getElementById('root'));
JSX is the best way to describe complex UI structures. Let's look at some JSX markup that declares a more elaborate structure than a single paragraph:
import React from 'react';import { render } from 'react-dom';// This JSX markup describes some fairly-sophisticated// markup. Yet, it's easy to read, because it's XML and// XML is good for concisely-expressing hierarchical// structure. This is how we want to think of our UI,// when it needs to change, not as an individual element// or property.render( <section> <header> <h1>A Header</h1> </header> <nav> <a href="item">Nav Item</a> </nav> <main> <p>The main content...</p> </main> <footer> <small>© 2018</small> </footer> </section>, document.getElementById('root'));
As you can see, there are a lot of semantic elements in this markup, describing the structure of the UI. The key is that this type of complex structure is easy to reason about, and we don't need to think about rendering specific parts of it. But before we start implementing dynamic JSX markup, let's create some of our own JSX components.
Here is what the rendered content looks like:
Components are the fundamental building blocks of React. In fact, components are the vocabulary of JSX markup. In this section, we'll see how to encapsulate HTML markup within a component. We'll build examples that show you how to nest custom JSX elements and how to namespace your components.
The reason that you want to create new JSX elements is so that we can encapsulate larger structures. This means that instead of having to type out complex markup, you can use your custom tag. The React component returns the JSX that replaces the element. Let's look at an example now:
// We also need "Component" so that we can// extend it and make a new JSX tag.import React, { Component } from 'react';import { render } from 'react-dom';// "MyComponent" extends "Compoennt", which means that// we can now use it in JSX markup.class MyComponent extends Component { render() { // All components have a "render()" method, which // retunrns some JSX markup. In this case, "MyComponent" // encapsulates a larger HTML structure. return ( <section> <h1>My Component</h1> <p>Content in my component...</p> </section> ); }}// Now when we render "<MyComponent>" tags, the encapsulated// HTML structure is actually rendered. These are the// building blocks of our UI.render(<MyComponent />, document.getElementById('root'));
Here's what the rendered output looks like:
This is the first React component that you've implemented, so let's take a moment to dissect what's going on here. You've created a class called MyComponent that extends the Component class from React. This is how you create a new JSX element. As you can see in the call to render(), you're rendering a <MyComponent> element.
The HTML that this component encapsulates is returned by the render() method. In this case, when the JSX <MyComponent> is rendered by react-dom, it's replaced by a <section> element, and everything within it.
Using JSX markup is useful for describing UI structures that have parent-child relationships. For example, a <li> tag is only useful as the child of a <ul> or <ol> tag—you're probably going to make similar nested structures with your own React components. For this, you need to use the children property. Let's see how this works. Here's the JSX markup:
import React from 'react';import { render } from 'react-dom';// Imports our two components that render children...import MySection from './MySection';import MyButton from './MyButton';// Renders the "MySection" element, which has a child// component of "MyButton", which in turn has child text.render( <MySection> <MyButton>My Button Text</MyButton> </MySection>, document.getElementById('root'));
You're importing two of your own React components: MySection and MyButton. Now, if you look at the JSX markup, you'll notice that <MyButton> is a child of <MySection>. You'll also notice that the MyButton component accepts text as its child, instead of more JSX elements. Let's see how these components work, starting with MySection:
import React, { Component } from 'react';// Renders a "<section>" element. The section has// a heading element and this is followed by// "this.props.children".export default class MySection extends Component { render() { return ( <section> <h2>My Section</h2> {this.props.children} </section> ); }}
This component renders a standard <section> HTML element, a heading, and then {this.props.children}. It's this last construct that allows components to access nested elements or text, and to render it.
Now, let's look at the MyButton component:
import React, { Component } from 'react';// Renders a "<button>" element, using// "this.props.children" as the text.export default class MyButton extends Component { render() { return <button>{this.props.children}</button>; }}
This component is using the exact same pattern as MySection; take the {this.props.children} value, and surround it with meaningful markup. React handles the messy details for you. In this example, the button text is a child of MyButton