Day 1 - June 27, 2022
Topics Covered
- Introduction to React
- React components
- JavaScript XML (JSX)
- Writing components using JSX
- Namespaces
- Using JavaScript expressions
- Introduction to React Native
Introduction to React
If you visit the reactjs.org website, you will learn that React is a JavaScript library for building user interfaces. Released by Facebook in 2013, React is used by companies big and small to develop user interfaces (UIs) for web, mobile and desktop applications. React is often compared to Angular but there are alot of differences between the two.
- Based on the Model-View-Controller (MVC) pattern, Angular is a front-end framework for building web applications. React, on the other hand, is for creating user interfaces (the "View" part of the MVC pattern).
- Angular works on the web page's DOM, updating the entire page when a change is made to the data driving our view. React implements a virtual DOM allowing for quicker updates since only the relevant portions are updated.
- Angular offers one-way and two-way binding but React only uses one-way. Since data only flows in one direction, React apps can be easier to debug.
In this course, we will learn how to use React (and React Native) to produce cross-platform applications.
React is component-based.
Components are reusable pieces of code used to render HTML markup (what the user sees) to the browser DOM (the render target). Components are similar to views in Handlebars but they can manage their own state.
React is declarative.
React components mix HTML markup and JavaScript together using a syntax called JavaScript XML (or simply JSX). When developing React components, there is no need to execute steps using imperative approaches. Instead, programmers can easily build interactive user interfaces (UI) by describing what they should look like. In other words, programmers will decide what HTML elements each component will render, not how they will be rendered.
- Declarative syntax
- A way of describing the code you want to write, without having to worry about how it's going to be implemented. In other words, you are specifying what needs to be done.
- Imperative syntax
- You supply a set of instructions to follow and the computer does what you want. In other words, you are defining how a task should be performed.
React components
In React, we will build our UI using JSX. JSX is just static text that represents the resulting HTML. On the initial render, React components and their JSX are no different than other template libraries. For example, Handlebars will render a template to HTML and a React component will do the same. However, React becomes much more interesting when data is changed. When using Handlebars, if the data changes we need to render the view again. With React, changes to the page are made automatically.
When data changes, refreshing a Handlebars view will take time but with React things update much more efficiently thanks to the virtual DOM. Reacts virtual DOM keeps a tally of the real DOM elements in memory and as data changes, it compares the new content with the already displayed content. Using diffing and patching, the virtual DOM can execute the imperative steps needed to update the HTML.
Remember, we are going to declare our components using declarative code and not worry about how to refresh the page. React will figure out exactly how the UI should be rendered or updated.
- Diffing
- Comparing old content with new content to figure out what's changed.
- Patching
- Executing the necessary DOM operations to render the new content.
JavaScript XML (JSX)
Remember, we will build React components using JSX syntax. JSX allows us to mix HTML and JavaScript together. The code we write is extracted from the HTML and transpiled into JavaScript statements. Browsers have no idea what JSX is and they don't need to since they only see the pure JavaScript after it is transpiled.
- Transpiler
- A source-to-source compiler which takes the source code of a program written in some programming language and converts it into another programming language.
Let's take a look at a simple "hello world" example. This is a React app, not a React Native app so the target is a web browser. As you study the example, you will notice a few things:
- The first few lines of the program will create a React DOM element from an HTML element in the browsers DOM.
- The last few lines build our UI, returning HTML to be rendered in the browser.
- The application combines JavaScript and XML. Since this is a React app the render target is the browser and so JSX has support for HTML tags. In other words, React already has components built-in for the common HTML elements that you use on a daily basis.
If you need to render multiple tags, they must be nested within a single tag. This is because React
needs
a root component to render. For example, you can't render adjacent elements like
<p><p><p>
. Look at the next code example and you will notice that the
<p>
and <button>
have been placed into a single
<div>
.
Tag names are case-sensitive. When writing HTML, as is done in the code example below, specify the tag names using only lowercase characters. When specifying non-html elements, start the tag with a capital letter. This convention makes it easier to scan the markup and spot the built-in HTML elements.
We can also pass HTML elements any of their standard properties. In the code example, we are passing the "foo" property. Since this is not a standard property, a warning may be logged but the HTML will still render.
JSX is a great way to describe even complex UI structures.
Writing components using JSX
Components are the fundamental building blocks of React.
In the above example, we are defining a component called MyComponent
. By extending
Component
we are creating a new, reusable, JSX element. Check out line 18, we are
rendering our custom tag. React replaces that tag with the JSX returned by MyComponent
.
Using JSX markup is not only useful for building reusable components but also for describing UI
structures that have parent-child relationships. As an example, a <li>
tag is useful
as a child of a <ul>
. To make this work, we can build our own components specifying
the children
property.
In the parent-child example, we are defining two React components. If you look at the JSX for the final
render, you will notice that <ChildComponent>
is a child of
<ParentComponent>
. You will also notice that <ChildComponent>
accepts text as its child instead of additional JSX elements. In both components,
{this.props.children}
acts as a placeholder for the content.
So, text is passed into the <ChildComponent>
and multiple
<ChildComponent>
tags are passed into the <ParentComponent>
yet
the rendered output includes the <div>
, <h1>
,
<p>
, <ul>
, and three <li>
tags. The browser
shows something like this:
Namespaces
So far, our components have used simple names and were not organized in any way. At times, it may be
benefitial to categorize or group our components into namespaces. Where we are using
MyComponent
, we could instead use MyNamespace.MyComponent
. This makes it clear
to other programmers that MyComponent
is part of the namespace MyNamespace
.
The above markup renders a <MyComponent>
element with two children, namely
<First>
and <Second>
. Notice that we refer to
<First>
and <Second>
using dot notation with their namespace. We
write <MyComponent.First>
and <MyComponent.Second>
.
If you are not a fan of nesting the components, you can unnest them by changing the import:
import { First, Second } from "./MyComponent";
. It is your decision how (and if) you will
use namespaces.
Using JavaScript expressions
The following examples shows how easy it is to mix JavaScript and HTML to build JSX. You will notice
that JavaScript variables can be passed in to components. Any valid JavaScript expression can be placed
between the { }
.
Even arrays can be used to build a dynamic UI.
Introduction to React Native
On Android, developers build Java apps while on iOS developers implement Swift apps. As a mobile app developer, you will have to learn both languages since picking only one platform is not realistic for success. As a React native developer, you only need to learn one language to target both platforms.
Earlier, we learned that the render target of React is the web browser. React Native on the other hand communicates with the underlying mobile OS to render native controls that behave and look as the OS user would expect. The good news is, the API we use to build React Native mobile apps is almost identical to that of React for the web. A main difference between the two flavours is the fact that React Native ships with components to be used on mobile platforms rather than with HTML elements.
You may be wondering if you can work around mobile apps all-together. In reality, this may be possible, at least at the early stages. But eventually you may find that mobile browsers lack many capabilities needed by your mobile apps. Here are a few things to consider:
- Many of the native controls built-in to mobile devices cannot be replicated by web browsers. For example, the date picker control. It usually looks very different in a web browser than as a native control on your mobile device.
- Many web apps assume the presence of a mouse but mobile devices are almost always interacted using a finger on a touch screen. Mobile platforms have a gesture system to deal with this type of interaction.
- Consistency and familiarity are important for a good user experience. Your app needs to look and behave as if it is part of the device.
- Since React Native uses actual components from the platform, it can easily deal with updates to the underlying OS. As controls are updated and improved, these updates are automatically rolled into your native app.
It is important to mention that although iOS and Android have several areas of overlap, it may not be feasible to write a single codebase shared entirely on both OS. You will want to take advantage of iOS-specific controls and Android specific controls to give your users the experience they expect. Concentrate on providing users the best experience possible rather than building a completely portable application.