You are on page 1of 56

Hello

React and TypeScript

Table of Contents
Introduction 0
Hello World Sample Code 1
Setting Up Samples 1.1
Component Basics 1.2
Components in Separate Files 1.3
Component Props and State 1.4
Component Interactivity 1.5
Accept User Input 1.6
Component Composition 1.7
Define Props and State Types 1.8
Form Input Types 1.9
Development Environment 2
IDE 2.1
Package Management 2.2
TypeScript Environment 2.3
Testing 2.4
Automation 2.5
React 3
TypeScript 4
TypeScript and React 5
References 6
Glossary 7
Glossary

2
Hello React and TypeScript

Hello React and TypeScript


The purpose of this book is to share my steps to setup a web project with React and
TypeScript. I have ran through many demos, tutorials, and videos on React and TypeScript
separately. Yet, finding up to date info on writing React apps with TypeScript was hard to do
at the time I wrote this.

When I started this book my main focus was on sharing my experience in establishing a
development environment and dealing with some of the quirks with coding React apps with
TypeScript. I thought that I wouldn't explore many of the concepts in React or TypeScript,
but as I learned more I decided to write about them. The book won't provide a deep
inspection of all things React or TypeScript, but I will go deeper than just a simple Hello
World.

This book will hone in on possible integrations of the two in terms of a development
environment, coding paradigms and style. The scope is small and this should not be taken
as a best practices guide. This is just my personal practice and there are many ways to do
this kind of development. I just hope that this can equip you to explore more practices for
your particular set of problems that can be solved with React and TypeScript.

Expectations
This is a very simple book, but it is probably most useful if you understand JavaScript.

Overview
We will start by jumping into some code samples with the proverbial Hello World. We will do
a few examples where we start with a very basic display the text "Hello World" and add new
features to demonstrate the basics of React with TypeScript.

Next, we break down the automation used in the sample. We review IDEs, package
management, build, transpiling... and more.

Then we review some interesting concepts in React and TypeScript.

Programming Language

Introduction 3
Hello React and TypeScript

This book will use ECMAScript 2015 (ES6). React and TypeScript discussions and source
code will be expressed in ES6 and above.

Code Samples and Examples


You can find the code samples and examples from the book on GitHub -
http://charleslbryant.github.io/hello-react-and-typescript.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 4.0


Unported License.

Introduction 4
Hello React and TypeScript

Hello World
To start this party off right we will jump right into a review of some code samples. We will be
using the proverbial Hello World app. I think this is a little more approachable than some of
the many ToDo demos and other more real world applications being used to tout React. I am
not saying the demos are bad, but React is a significant paradigm shift for many developers
and I think a slow build up is good for old dogs like myself trying to learn new tricks.

Exploring Hello World is great to get you grounded before exploring more "real world" type
applications. We will even take the basic Hello World a little farther than simply displaying
text to get exposure to the core concepts in React.

Sample Source
You can download the code samples with the link provided for each sample. You can also
get a copy of the source from the GitHub repository by cloning

https://github.com/charleslbryant/hello-react-and-typescript.git

Thoughts for More Robust Scalable App


The samples are limited in scope because this is just an introduction. Additional topics that
you can explore explore include:

ReactRouter
Immutable.js
Flux
Redux
GraphQL
Relay
Application Configuration Management
Session Management
Caching
Security
Tenant Management
User Management
Role Management
Authentication

Hello World Sample Code 5


Hello React and TypeScript

Cookie
Token
OAuth
Authorization
and much more

Hello World Sample Code 6


Hello React and TypeScript

Setting Up Samples

Requirements
All of the code samples have a couple requirements

npm package manager (Node 5.2.0 used in development)


IE 10+ or similar modern browser that supports the History API

This first sample is the source for the basic development environment. This includes the
packages and automation that will be used in the samples.

Note - to get the latest version of packages and automation you should clone the repository
from root, https://github.com/charleslbryant/hello-react-and-typescript.git . We will make
updates as we move along with new samples so version 0.0.1 is only a starting point.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.1

Installing
To install a sample you need to run npm to get the required dependencies. You should open
a console at the root path of the sample directory and run
npm install

Then

tsd install

These commands will install the required npm packages and TypeScript Typings.

Run the Sample


To run the samples, open a console at the sample directory and run

gulp

This will kick off the default gulp task to run all the magic to compile TypeScript, bundle our
dependencies and code into one bundle.js file, and move all of the files need to run the
application to a dist folder, open the index.html page in a browser, and reload the site when

Setting Up Samples 7
Hello React and TypeScript

changes are made to source files.

Setting Up Samples 8
Hello React and TypeScript

Basic React Component


This is a very basic example of a single React component. We could make it even simpler,
but this example is still basic enough to start with.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.2

src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello World</title>
<link rel="stylesheet" href="css/bundle.css"/>
</head>
<body>
<div id="app"></div>
<script src="scripts/bundle.js"></script>
</body>
</html>

If you don't understand this, I recommend that you find an introduction to HTML course
online.

The important part of this file is <div id="app"></div> . We will tell React to inject its HTML
output to this div.

src/main.tsx

Component Basics 9
Hello React and TypeScript

/// <reference path="../typings/tsd.d.ts" />


import * as React from 'react';
import * as DOM from 'react-dom';

const root = document.getElementById('app');

class Main extends React.Component<any, any> {


constructor(props: any) {
super(props);
}

public render() {
return (
<div>Hello World</div>
);
}
}

DOM.render(<Main />, root);

If you know JavaScript, this may not look like your mama's JavaScript. At the time I wrote
this ES6 was only 6 months old and this sample is written with ES6. If you haven't been
following the exciting changes in JavaScript, a lot of the syntax may be new to you.

This is a JavaScript file with a .tsx extention. The .tsx extenstion let's the TypeScript
compiler know that this file needs to be compiled to JavaScript and contains React JSX. For
the most part, this is just standard ES6 JavaScript. One of the good things about TypeScript
is we can write our code with ES6/7 and compile it as ES5 or older JavaScript for older
browsers.

Let's break this code down line by line.

/// <reference path="../typings/tsd.d.ts" />

The very top of this file is a JavaScript comment. This is actually how we define references
for TypeScript typing files. This let's TypeScript know where to find the definitions for types
used in the code. I am using a global definition file that points to all of the actual definitions.
This reduces the number of references I need to list in my file to one.

import * as React from 'react';


import * as DOM from 'react-dom';

Component Basics 10
Hello React and TypeScript

The import statements are new in JavaScript ES6. They define the modules that need to
be imported so they can be used in the code.

const root = document.getElementById('app');

const is one of the new ES6 variable declaration that says that our variable is a constant or

a read-only reference to a value. The root variable is set to the HTML element we want to
output our React component to.

class Main extends React.Component<any, any> {

class is a new declaration for an un-hoisted, stict mode, function defined with prototype-

based inheritance. That's a lot of fancy words and if they mean nothing to you, its not
important. Just knowing that class creates a JavaScript class is all you need to know or
you can dig in at https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Classes.

Main is the name of the class.

extends says that the Main class will be created as a child of the React.Component<any,

any> class.

React.Component<any, any> is a part of the TypeScript typing definition for React. This is

saying that React.Component will allow the type any to be used for the components state
and props objects (more on this later). any is a special TypeScript type that basically says
allow any type to be used. If we wanted to restrict the props and state object to a specific
type we would replace any with the type we are expecting. This looks like generics in C#.

constructor(props: any) {
super(props);
}

The contructor method is used to initialize the class. In our sample, we only call
super(props) which calls the contructor method on our parent class React.Component
passing any props that were passed into our constructor. We are using TypeScript to define
the props as any type.

Component Basics 11
Hello React and TypeScript

In additon to calling super we could also initialize the state of the component, bind events,
and other tasks to get our component ready for use.

public render() {
return (
<div>Hello World</div>
);
}

Maybe the most important method in a React component is the render method. This is
where the DOM for our component is defined. In our sample we are using JSX. We will talk
about JSX later, just understand that it is like HTML and outputs JavaScript.

JSX is not a requirement. You could use plain JavaScript. We can rewrite this section of
code as

public render() {
return (
React.createElement("div", null, "Hello World")
);
}

The render method returns the DOM for the component. After the return statement you
put your JSX. In our sample, this is just a simple div that says Hello World. It is good practice
to wrap your return expression in parenthesis.

DOM.render(<Main />, root);

Lastly, we call DOM.render and pass Main , the React component we just created, and
root , the variable containing the element we want to output the component to.

That's it, pretty simple and something we can easily build upon.

Component Basics 12
Hello React and TypeScript

Components in Separate Files


This sample demonstrates how to split your components into multiple files. It is still just the
simple display Hello World, but now it is modular and reusable.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.3

The HTML is still exactly the same as sample #2.

src/main.tsx
We only have two changes to explore the main.tsx file.

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';


import * as DOM from 'react-dom';
import HelloWorld from './helloworld';//Add new import

const root = document.getElementById('app');

class Main extends React.Component<any, any> {


constructor(props: any){
super(props);
}

public render() {
return (
<HelloWorld />//Return our new HelloWorld component
);
}
}

DOM.render(<Main />, root);

Let's look at the differences.

import HelloWorld from './helloworld';

Components in Separate Files 13


Hello React and TypeScript

We added a new import to import the HelloWorld component.Notice that we use a relative
path to the component with no extension.

return (
<HelloWorld />
);

Instead of returning the markup directly, we are returning the HelloWorld component and
delegating the rendering of the markup to this new component. By having the markup in a
separate component we can add <HelloWorld /> multiple times and only have to change it
in one place. We have a single point of truth for what the markup for Hello World should be
and we can reuse it.

To use external components they have to be in scope, which is why we imported it. Another
point to make is that a React component needs to have only one root element. If we were to
add more markup or components here, we would have to wrap it in a parent element.

Example:

return (
<div>
<HelloWorld />
<HelloWorld />
</div>
);

This would display "Hello World" twice. Notice how we started the component name with an
uppercase letter, React expects components to start with uppercase and DOM elements to
start with lowercase.

src/helloworld.tsx

Components in Separate Files 14


Hello React and TypeScript

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloWorld extends React.Component<any, any> {


constructor(props: any){
super(props);
}

public render() {
return (
<div>Hello World!</div>
);
}
}

If you paid attention to the previous sample you will notice that this is almost exactly like the
old main.tsx. We copied main.tsx to a new file called helloworld.tsx. We gave the component
class a new name and we deleted the import for DOM. We don't need to import DOM
because we don't need to call anything from React.DOM.

That was pretty easy so I don't think that we need to review this code.

Components in Separate Files 15


Hello React and TypeScript

Component Props and State


This sample gives an basic example of using props and state in your components.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.4

src/main.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';


import * as DOM from 'react-dom';
import HelloWorld from './helloworld';

const root = document.getElementById('app');

class Main extends React.Component<any, any> {


constructor(props: any){
super(props);
}

public render() {
return (
<div>
<HelloWorld defaultName='World' />
</div>
);
}
}

DOM.render(<Main />, root);

The change to main.tsx is minor. Here is the one change.

return (
<div>
<HelloWorld defaultName='World' />
</div>
);

Component Props and State 16


Hello React and TypeScript

We are just passing defaultName to the HelloWorld component. This is doing exactly what
you think it is, its setting the default value for who we are saying Hello to. Notice that this
name is explicit in defining this input. It is a default value, the HelloWorld component can
change this value and the assumption is that it may be changed.

Another thing to notice is the camelCasing.

All DOM properties and attributes (including event handlers) should be camelCased to be
consistent with standard JavaScript style. https://facebook.github.io/react/docs/dom-
differences.html

src/helloworld.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloWorld extends React.Component<any, any> {


constructor(props: any){
super(props);
this.state = { name: this.props.defaultName };
}

public render() {
return (
<div>
Hello { this.state.name }!
</div>
);
}
}

We made two changes to helloworld.tsx, but they are significant to the interactivity of our
little application.

constructor(props: any){
super(props);
this.state = { name: this.props.defaultName };
}

In the constructor we are setting the initial state for this component. this.state is a plain
JavaScript object. It is a mutable representation of the model for the view. this.state is
expected to change over time as events occur in the component. In this sample we are

Component Props and State 17


Hello React and TypeScript

initializing this.state with an object literal { name: this.props.defaultName } .

this.props.defaultName was passed in from main.tsx. this.props is also a plain JavaScript

object. The difference being it is an immutable representation data used by the component.
this.props should not be changed and they are passed in by parent components. If you

change props, they will be overwritten when the parent rerenders. Mutating props puts your
component in an inconsisten state, so don't do it.

return (
<div>
Hello { this.state.name }!
</div>
);

The next change is to the return value of the render method. We are using
this.state.name to set the name dispayed in the UI.

In this sample we use this.props to initialize this.state . We know that we want to update
the name of who we say hello to, so we are using a state object to represent the name. If we
didn't want to update name, we could use props directly. For example

return (
<div>
Hello { this.props.name }!
</div>
);

Using props like this is saying that we don't expect this component to change the name. In
fact, to make it explicit, we changed the name from defaultName to name . Also, main.txt
would have to be changed from passing defaultName to name . Using props means we
expect the parent to be in control of changing the value of props. Using state means we
expect the component to be in control of its own state.

Component Props and State 18


Hello React and TypeScript

Component Interactivity
This sample gives an basic example of using adding interactivity to a component.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.5

src/helloworld.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloWorld extends React.Component<any, any> {


constructor(props: any){
super(props);
this.state = { name: this.props.defaultName };
}

public handleChange(event: any) : void {


this.setState({ name: "Charles" });
}

public render() {
return (
<div>
Hello { this.state.name }!
<button
name = "Update"
onClick = { e => this.handleOnClic(e) }
>Update</button>
</div>
);
}
}

To add interactivity we:

added an element for a user to interact with


created a method to handle an event triggered by user interaction
bound the new element's onClick event to the new event handler method

Component Interactivity 19
Hello React and TypeScript

public handleOnClick(event: any) : void {


this.setState({ name: "Charles" });
}

This is a new method to handle the click event. We expect callers of this method to send the
event as an argument so we defined the argument as type any so we can accept any
event. We could define a specific or generic event type and restrict the argument to that
type. We also define the method as returning void or nothing.

In the method we are calling this.setState and updating the value of name . When we call
this.setState it causes the component to re-render with the new state.

return (
<div>
Hello { this.state.name }!
<button
name = "Update"
onClick = { e => this.handleOnClick(e) }
>Update</button>
</div>
);

We are adding a new HTML element, button (remember that HTML elements start with
lowercase letter). The interesting bit is that we are binding the element's onClick event to
the handleOnClick method. To bind the event handler with the event we are using the new
ES6 arrow function expression to simplify function context binding. Notice that the event
handler is camelCased which is consistent with JavaScript style.

Function Context Binding


In the end, React is just plain JavaScript. The React Team has resisted the urge to add a lot
of magic and have made strides to remove magic to reduce coupling. Magic is the
encapsulated work that is hidden behind abstractions. When a library does work behind the
scenes without you knowing it, its magic. Reducing this hidden work helps to losen coupling
and that is a good thing because it enables reuse. The React team believes our code
shouldn't have a lot of coupling to React.

One example of this, related to our use of the arrow function above, is function context
binding. There was a time when React automatically bound functions to this . If you aren't
a JavaScript developer there is a chance that you don't know that this in JavaScript is

Component Interactivity 20
Hello React and TypeScript

different from this in C# or Java or self in Ruby.

In some strongly typed languages, this is bound to an object instance. In JavaScript


this is bound to the function it is called in. This causes a lot of confusion, but this

decoupling of this from their parent function allows us to reuse functions outside of the
parent, powerful and dangerous at the same time.

To get this function reuse we can define the context for a function and have this represent
what we want it to. In our example the arrow function is assigning this from the class
HelloWorld to the handleOnClick method. If we wanted, we could use this same method in

say a GoodByeWorld class and the arrow function could set the context of the handleOnClick
method.

Without the arrow function we would use JavaScripts bind method to achieve the same
effect. The arrow function is just some syntactic sugar for
onClick = { handleOnClick().bind(this) }

You can get more on arrow functions here https://developer.mozilla.org/en-


US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.

Component Interactivity 21
Hello React and TypeScript

Accept User Input


This sample gives an basic example of accepting user input.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.6

src/helloworld.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloWorld extends React.Component<any, any> {


constructor(props: any){
super(props);
this.state = { name: this.props.defaultName };
}

public handleOnChange(event: any) : void {


this.setState({ name: event.target.value });
}

public render() {
return (
<div>
<div>
<input
onChange={ e => this.handleOnChange(e) }
/>
</div>
<div>
Hello { this.state.name }!
</div>
</div>
);
}
}

The significant changes here are we removed the button and handleOnClick method. We
also added a text box and a handleOnChange method to handle changes as a user adds
input to the text box.

Accept User Input 22


Hello React and TypeScript

public handleOnChange(event: any) : void {


this.setState({ name: event.target.value });
}

This is a new method to handle the onChange event. In the method we are calling
this.setState and updating the value of name in this.state to the value of the target

element passed in the event.

public render() {
return (
<div>
<div>
<input
onChange={ e => this.handleOnChange(e) }
/>
</div>
<div>
Hello { this.state.name }!
</div>
</div>
);
}

Here we added an input element and set its default value to this.props.name . We also
bound the text box's onChange event to handleOnChange method.

With these changes we have implemented a unidirectional data flow.

1. When the user enters something in the text box it triggers the onChange event.
2. The onChange event is handled by the handleOnChange method.
3. The handleOnChange method updates the value of name in this.state and triggers a
re-render of the component with this.setState .
4. this.setState ends in a call to the render method that updates the name in our

"Hello" message.

State is only changes as the result of an event. The Hello message is no bound to an
external model state and can only be updated as a result of an event being triggered by user
input. This is different than two way binding or bi-directional data flow where changes in a
model can also update the state of a view.

Accept User Input 23


Hello React and TypeScript

Unidirectional Data Flow (UDF)


event > event handler > state > render

Components are representations of the state of a view over time. As events are triggered
over time they update state and re-render the component with the new state. The flow can
be seen as a stream of events that flow in one direction that eventually update component
state causing a component to re-render. If you know about CQRS, event streaming, or
stream processing, there are similar concepts in each. UDF is a redundant theme in learning
React, hence a redundant theme in this book.

The sample is a simple naive example because we aren't dealing with external or persisted
data. The scope of the example makes it a little hard to understand UDF. In the example we
don't have to worry about updating an external store.

If you are having trouble understanding UDF, when you learn about Flux it will makes more
sense. The Flux architecture helps you visualize data flow in a circular one way round trip.
Even though it may be hard to see UDF within the context of a single component the same
event flow is used to accomplish UDF in React whether within a single component, a Flux
architecture, or using Relay (another Facebook library). When you get into Flux or other data
flow patterns or libraries, UDF will be expanded to add additional concepts into the data flow.

UDF vs Bi-directional Data Flow


The important thing to notice about UDF is that we aren't attempting to create a complex bi-
directional view binding with some external model. We are binding to the state modeled
within a component with no dependency or complex mapping to some external data model.
The component is responsible for expressing its own state, updating its state, passing
properties to its child components, and re-rendering itself and children when state changes
as the result of some event.

If we were to use a bi-directional binding to an external model, we would not know why state
is being updated. Any number of views could have the same binding to the same model.
With bi-directional binding a change to a view or model could cause updates to multiple
models or views and it becomes hard to understand the data flow, especially when you are
trying to solve a Sev1 incident.

If you'd like to know more about UDF, there is a lot about it online that can be found with a
simple search. Actually, the original MVC pattern is an example of UDF. It was distorted
when it moved to web clients. If you'd like to dig into the theory behind React and UDF, you
can research Functional Reactive Programming -
https://en.wikipedia.org/wiki/Reactive_programming.

Accept User Input 24


Hello React and TypeScript

Accept User Input 25


Hello React and TypeScript

Component Composition
This sample gives a basic example of refactoring the Hello World application by composing
the UI with modular components.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.7

src/helloworld.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';


import HelloForm from './helloform';
import HelloContent from './hellocontent';

export default class HelloWorld extends React.Component<any, any> {


constructor(props: any){
super(props);
this.state = { name: this.props.defaultName };
this.handleChange = this.handleChange.bind(this)
}

public handleChange(event: any) : void {

this.setState({ name: event.target.value });


}

public render() {
return (
<div>
<HelloForm
name = { this.state.name }
handleChange = { this.handleChange }
/>
<HelloContent
name = { this.state.name }
/>
</div>
);
}
}

Component Composition 26
Hello React and TypeScript

The HelloWorld component is updated to compose the same UI as the previous example
using two modular components, HelloForm and HelloContent .

import * as React from 'react';


import HelloForm from './helloform';
import HelloContent from './hellocontent';

To compose with components the components you want to compose have to be in scope. To
do this we import the components. HelloForm and HelloContent are imported by using the
import statement with the from value being the relative path to the component with no

extension.

public render() {
return (
<div>
<HelloForm
name = { this.state.name }
handleChange = { this.handleChange }
/>
<HelloContent
name = { this.state.name }
/>
</div>
);
}

The actual composition occurs in the render method. We add the HelloForm and
HelloContent components. Notice that the name of the components start with uppercase to

differentiate them from HTML elements. Each of the components accept some properties
and we pass them with a syntax that is similar to defining HTML attributes.

By composing UIs in this manner we move from an imperative style of building UIs to a
declarative one. Instead of defining every element and attribute we want to use in the UI we
delegate the definition to a modular reusable component.

Since the modular components are reusable we can compose multiple UIs with them. We
can compose with components developed by other teams. We get to focus on the unique
aspects of our domain and delegate other lower level concerns to modular components.

Component Composition 27
Hello React and TypeScript

src/helloform.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloForm extends React.Component<any, any> {


constructor(props: any){
super(props);
}

public render() {
return (
<div>
<input
value={ this.props.name }
onChange={ e => this.props.handleChange(e) }
/>
</div>
);
}
}

Here we have a new component responsible for the collecting user input for our tiny
application. By now this code should be familiar. We just moved the input element from the
HelloWorld component and encapsulated it in this new component.

For this simple example we are storing all of our components in one folder. As your
application grows you may want to use a folder structure that makes the number of
component files more manageable. When you are at the point of doing this you will have to
address the reference path for the TypeScript typings. It will become a maintenance issue
having to keep the path in sync as you move components and build new folder structures,
but we won't go into that just yet.

src/hellocontent.tsx

Component Composition 28
Hello React and TypeScript

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloContent extends React.Component<any, any> {


constructor(props: any){
super(props);
}

public render() {
return (
<div>
Hello { this.props.name }!
</div>
);
}
}

This is a component responsible for displaying the hello message. Again, this component is
a result of encapsulating this section of the DOM out of the HelloWorld component.

Stateless Components
One interesting observation about these components is that they are stateless. They don't
hold any state and they rely on a parent component to pass props to it in order to do its
work. This includes event handlers and data as you can see in the sample code.

When possible using stateless components are preferred in React. They help to improve
performance because they lessen the amount of processing that React has to do with the
component.

Component Composition 29
Hello React and TypeScript

Define Props and State Types


This sample gives shows how we can get more type checking to protect from errors by
defining the expected type for Props and State.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.8

src/interfaces.d.ts
interface IHelloFormProps {
name: string;
handleChange(event: any): void;
}

interface IHelloContentProps {
name: string;
}

First order of business is to define the new types. Since we aren't passing in state to any
components we won't define types for state objects, but its the same concept.

We are defining the types in a type definition file (file extention d.ts). This is the same type of
file that we get from DefinitelyTyped. This is a scaled down example, but you can also use
the same technique to build your own type definitions for external modules that don't have a
current definition.

interface IHelloFormProps {

interface is TypeScripts declaration for an interface. It is a way to declare a contract for

the shape of a type. Shape in this sense is a collection of methods and properties along with
their associated types. When you create objects of the type defined by the interface it is
expected that the object will have the same shape. If it doesn't, TypeScript will give an error
at compile time. If your IDE supports it, you can also get design time errors, code
completion, etc.

These types are not used in the JavaScript that is generated, it is just used for type checking
by the TypeScript compiler.

Define Props and State Types 30


Hello React and TypeScript

name: string;
handleChange(event: any): void;

Here we are defining the expected shape of objects that extend IHelloFormProps . Objects
are expected to have a property named name of type string and a method named
handleChange that accepts an argument named event of type any and has a return type

void .

Hopefully, you can understand the IHelloContentProps interface from the explanation of
IHelloFormProps .

src/helloform.tsx
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts" />

import * as React from 'react';

export default class HelloForm extends React.Component<IHelloFormProps, any> {


constructor(props: IHelloFormProps) {
super(props);
}

public render() {
return (
<div>
<input
value={ this.props.name }
onChange={ e => this.props.handleChange(e) }
/>
</div>
);
}
}

The HelloWorld component is updated to use the new types, IHelloFormProps and
IHelloContentContent .

/// <reference path="./interfaces.d.ts" />

Define Props and State Types 31


Hello React and TypeScript

Here we are adding a reference to the new type definition file we created to hold our type
interfaces.

export default class HelloForm extends React.Component<IHelloFormProps, any> {

In our class declaration we are saying that we want to extend React.Component using
objects of type IHelloFormProps .

constructor(props: IHelloFormProps) {

In the constructor we update the props argument to be of type IHelloFormProps .

src/hellocontent.tsx
/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloContent extends React.Component<any, any> {


constructor(props: any){
super(props);
}

public render() {
return (
<div>
Hello { this.props.name }!
</div>
);
}
}

This is very similar to the change we made to HelloWorldForm component.

Define Props and State Types 32


Hello React and TypeScript

Form Input Types


Coming Soon!

Form Input Types 33


Hello React and TypeScript

Development Environment
One of the first thing to do before starting a new project is setting up a development
environment. It is important to establish a good working environment with the tools and
dependencies for effective and efficient development. Although we want an environment for
React and TypeScript development, it isn't very different than a standard JavaScript setup.

Development Environment 34
Hello React and TypeScript

IDE
To code React applications with TypeScript you can use any text editor. To make things
easier it may be worth it to get an integrated development environment (IDE) that has
features and plug-ins specifically for JavaScript and TypeScript development.

Choosing an IDE is a religious experience so I won't start an ideological war by saying use
this or that IDE. I would recommend looking at some of the popular ones active today:

Aptana - aptana.com
Atom - atom.io
Brackets - brackets.io
Cloud9 - c9.io - cloud based editor
Eclipse - eclipse.org
Komodo - komodoide.com
NetBeans - netbeans.org
Nuclide - nuclide.io/
Sublime - sublimetext.com
Vim - vim.org
Visual Studio Code - code.visualstudio.com
WebStorm - jetbrains.com/webstorm

I am probably missing some that others would consider popular. This is just a tip of the IDE
iceberg to give some ideas on what's available. Initially, the IDE you choose is not important.
I can say that I enjoy Atom, Brackets, Cloud9, Sublime and Visual Studio Code. Also, I am
intrigued by Facebooks IDE Nuclide because it is based on Atom and made with React
development in mind.

I won't vote for one over the other because they all work. Try a few IDE's and pick one that
fits your development style without having to jump through hoops to do common tasks. If
your goal is to get up to speed on React and TypeScript development, don't spend too much
time trying to find and configure the perfect IDE.

IDE 35
Hello React and TypeScript

PackageManagement
There can be many dependencies that need to be managed to enable development with
external libraries, frameworks, tools, and APIs. Since we are talking about a JavaScript
project, we will use the popular Node Package Manager (NPM) to manage most of our
dependencies. NPM is like NuGet or Maven, but for node modules.

If you don't have npm, you'll have to install it (https://docs.npmjs.com/getting-


started/installing-node).

Initialize NPM
To get going with npm create a directory for your project (name isn't important). Then open a
command prompt at the new directory. Now initialie npm for the project, run

npm init

This starts a utility to help you setup your project for npm. I usually update the description,
version and author info. The utility takes that data you enter and creates a package.json file.
You can think of package.json like package.config for NuGet or pom.xml for Maven. This file
will have a listing of all of the dependencies for the project.

Initial Dependencies
We will be using a few dependencies that we will install with NPM. We are able to separate
dependencies that are only needed for development from dependencies that are needed at
runtime. This is useful when you want to distribute an application. User's of your app won't
have to download your development dependencies if they don't need them.

Runtime Dependencies
Here is a list of our initial runtime dependencies

bootstratp - CSS styling.


react - view engine.
react-dom - react dom rendering module.
react-router - routing.
toastr - UI alerts and messaging.

Package Management 36
Hello React and TypeScript

To install them run


npm install --save bootstrap react react-dom react-router toastr

Development Dependencies
Here is a list of our development dependencies

browserify - bundle up JavaScript dependencies into a single file.


browser-sync - refresh browser after changes.
del - delete files.
eslint - lint our JavaScript files.
gulp - automate build and development workflow. This is like NAnt, Nake, Make and
other task runners.
gulp-concat - bundle css files.
gulp-connect - run a webserver with LiveReload.
gulp-eslint - run eslint in gulp tasks.
gulp-typescript - run typescript compile in gulp tasks.
gulp-sourcemaps - generate TypeScript sourcemaps.
stream-combiner2 - turn a series of streams into a single stream to enable single error
events.
typescript - TypeScript dependencies.
vinyl-source-stream - convert Browserify stream to vinyl stream used by Gulp.
watchify - persistent browserify bundler to speed up builds.

To install them run


npm install --save-dev browserify browser-sync del eslint gulp gulp-concat gulp-connect
gulp-eslint gulp-typescript gulp-sourcemaps stream-combiner2 typescript vinyl-source-stream
watchify

Package Management 37
Hello React and TypeScript

TypeScript Environment

TypeScript Definition Files


To get ready for TypeScript development we need typings for React. An easy way to pull in
typings is with tsd, a package manager to search and install TypeScript definition files.
npm install -g tsd

You can install TypeScript typings with tsd. When you install your typings are saved in
tsd.json. You can create a tsd.json file by running
tsd init

To install a typing, for example react, you can run tsd


tsd install react --save

You can find a lot of TypeScript definition at


https://github.com/DefinitelyTyped/DefinitelyTyped.

To make it easier, in the source code there is a tsd.json that includes all of the typings
necessary for the demo application. To install these typing just run
tsd install

This will get the typings and place them in the typings folder. In the typings folder there is a
tsd.d.ts file that has all of the typing references bundled into one file.

TypeScript Configuration
There are a lot of configurations that you can set for the TypeScript compiler. To help
manage the settings you can create a tsconfig.json file to hold the configuration.

We take advantage of this file in the Gulp task to compile TypeScript. Actually, in our gulpfile
we use the tsconfig in tsc.createProject('tsconfig.json') to create a project that we can
use in our compile task.

TypeScript Environment 38
Hello React and TypeScript

Testing
Coming Soon!

Sneak Peak - The test framework will be Jest, Facebooks fork of Jasmine.

https://github.com/facebook/jest/tree/master/examples/typescript

Testing 39
Hello React and TypeScript

Automation
Next, we will setup our build automation. The primary reason we want to do this is so we
don't have to run the commnand line every time we make changes. In fact, our build
automation will allow us to automatically see the results of changes in the browser after we
save them. We can start one simple task in the command line and the automation will take
care of linting, compiling, bundling, refreshing the browser and more when ever we make
changes.This allows us to get very fast feedback on changes. If we have fast unit tests, this
automation will also help us keep some bugs from creeping into our app. So, build
automation will not only make development go faster, provide faster feedback, help keep
quality high, it will also give us a consistent way to build our application.

Gulp
We are going to use Gulp for our task runner and Browserify to bundle. To be honest, I was
going to switch to npm and WebPack. The React community seems to have embraced
WebPack as the defacto bundler. So, there are plenty of examples online. Also, I went with
Browserify because the learning curve is bigger for WebPack and I don't want it to be a
distraction.

Actually, we are going to use Gulp 4. At the time of this writing, this new version of Gulp
hasn't been released. The main reason I decided to go with this early release version is that
it has new features that will make our automation a little easier to work with.

The main feature we want to exploit is the new task execution system. Before Gulp 4, all
tasks ran in parallel. This was great becuse it made things fast, but many times there is a
series of tasks that need to run in sequence. Getting tasks to run sequentially can get
complicated. With the new task execution we can define a pipeline of tasks and decide if we
want parallel or series execution.

First we need to install Gulp 4. Because I already have Gulp installed I need to firt uninstall
Gulp and then reinstall version 4.
npm uninstall --save-dev gulp

npm install --save-dev "gulpjs/gulp#4.0"

npm install --save-dev "gulpjs/gulp-cli#4.0"

Automation 40
Hello React and TypeScript

If you have worked with Gulp before, you'll notice that I installed gulp and gulp-cli separate.
The CLI was moved to a separate module to make the core install lighter for use cases that
don't need the CLI.

Vinyl
Just some background on vinyl because it is interesting to me. Gulp uses vinyl, a virtual file
format, which is why we don't need to create temp files to pass through automation
workflows like Grunt. Files are converted to vinyl ( gulp.src() ) and can be piped to different
gulp middleware as they flow through gulp tasks and finally converted back to a physical file
( gulp.dest() ). Under the hood gulp uses the vinyl-fs module to work with files on a local file
system, but the "interesting to me" part of vinyl is that modules can be created to use vinyl to
work with any file source, DropBox, S3, Azure Storage... I haven't had a need to connect to
external files, but it was exciting to realize that I can come up with new use cases to
transform my build automation process with vinyl modules.

Automation 41
Hello React and TypeScript

React
React is a library for building composable user interfaces. It encourages the creation of
reusable UI components which present data that changes over time.

Pete Hunt - http://facebook.github.io/react/blog/2013/06/05/why-react.html

Tom Occhino and Jordan WalkeReact announced React as an open source project at
JSConfUS 2013 - https://www.youtube.com/watch?v=GW0rj4sNH2w. Pete Hunt followed up
in a talk he gave at JSConfEU and JSConfAsia. There were a lot of nay sayers as a result of
the announcement and Pete titled his talk after a sarcastic Twitter post, "React: Rethink Best
Practices." This talk goes into the design decisions behind React and gives solid reasons for
using it - https://www.youtube.com/watch?v=DgVS-
zXgMTk&feature=iv&src_vid=x7cQ3mrcKaY&annotation_id=annotation_3048311263.

For you functional minded folks, another way to think of React is as a way of writing
declarative views where a view is a function of data defined in terms of the state of data in
some point in time.

v = view
p = props
s = state
v = f(p,s)

React is a small library with a simple API. It is not an MVC framework. You can think of
React as the view in MVC. It just renders views and enables interactivity by responding to
events.

Facebook and Instagram developed React and actually use it in production on their very
large scale applications and development teams. You can write isomorphic applications by
rendering views on both the client and server with the same JavaScript code. With the
announcement of React Native you can render views on any device (IOS, Android...). Netflix
is using React to render UIs on televisions! Its hard to deny React as a viable option for
application development.

I think React has delivered on redefining best practices for efficiently developing and
rendering views.

React Component

React 42
Hello React and TypeScript

A React Component is just a JavaScript function. The function accepts an immutable object
named props and has a render function that can render a section of DOM which can include
child components. Having child component functions inside component functions allows you
to build up a DOM tree. The React Component encapsulates behavior to manage its state
and handle its life cycle events.

Basically, a React Component is a JavaScript function that owns a section of the DOM.
Components can be composed together with other components to build up a UI. If you build
components properly they become like Legos for UIs. Small, focused on a specific concern,
easy to reuse and repurpose them to build UIs to solve various problems.

Composition is achieved through a tree structure with a component parent-child hierarchy.


You can think of compositions as functions in functions or components in components with
the hierarchy modeled as a DAG. There can only be one root component, but there can be
many levels of children. Each component handles its own state and rendering its part of the
DOM in a UI.

JSX
React doesn't have a template system, but you can use markup that feels like HTML by
using JSX. JSX is an extension of JavaScript that allows you to use XML like constructs in
your components to define your view structure.

JSX is not a template it is a high level abstraction of the DOM. JSX must be transformed
before it is used. When you use a JSX transformer, with tools like Babel or TypeScipt
compiler, JSX elements are transformed to plain JavaScript React.createElement methods.

JSX gives us an abstraction that allows us to be more declarative while writing our view. We
are using familiar HTML like structure to declare what the DOM structure is. As opposed to
defining the DOM with a lot of React.CreateElement calls. Building a UI with
React.CreateElement is still declarative, but the declaration with JSX is a little easier to grok

as a traditional web developer or designer.

There are some difference from HTML that you have to watch out for while writing JSX. You
can't use JavaScript keywords. For instance, instead of defining a CSS class attribute on
your JSX element you use className . Instead of using for to relate a label with an
element you use htmlFor .

When you want to render HTML elements you use lowercase as first letter of JSX element.

React 43
Hello React and TypeScript

<div className="container">
<label htmlFor="hello">Hello</label>
<input type="text" id="hello" />
</div>

When you want to render a React Component use uppercase as first letter of the JSX
element.

<HelloWorldComponent displayName="Charles" />

You could write your views with React.createElement instead of JSX, but JSX is more
approachable by designers and developers that aren't comfortable with JavaScript.

Writing React components with JSX we move from writing views with imperative, hard to
understand, underpowered HTML template logic to writing declarative, highly expressive
functions to manage the state of components with JavaScript. It's a win-win. Developers can
write logic with a proper development language and not a weird restrictive template
abstraction and Designers still get the comfort of working with HTML like structures.

React Component Rendering


One of the great benefits of using React is the speed at which it can update the DOM.
Speed is a core value of the team that develops React. They achieved speed by relying on a
virtual representation of the DOM and some clever algorithms that allows React to make
changes to the DOM faster than traditional view engines.

React uses somthing it calls a two passes rendering process. First it generates the markup
in the first pass. Then it attaches events after the markup is injected in the document. This
allows React to generate documents on the server and send it to a client and React will
recognize that the markup is already done so it just attaches the events and the app
continues functioning from there. This makes it fast for the initial view of the app. Then the
speed of React keeps the app functioning fast.

Rendering of React components start when you call ReactDOM.render or setState


methods. These methods kick of a process called reconciliation
(http://facebook.github.io/react/docs/reconciliation.html). Reconciliation is the process that
React uses to collect the minimum amount of changes to efficiently render views.

You call setState any time the state for the component is updated. setState will mark the
component as dirty to help React optimize what actually needs to be re-rendered. When a
component is marked for rendering the children in its sub-tree will also be rendered. At the

React 44
Hello React and TypeScript

end of each event loop React will call render on all of the components that have been
marked dirty by setState . This means that during a single cycle React can render multiple
components in one batch.

If you want to improve performance of rendering you can define shouldComponentUpdate to


short circuit rendering on components that should not re-render based on comparison of
previous and next props and state. If you use immutable data structures, like immutable.js,
for props and state, this comparison becomes trivial since you don't have to do deep
comparison of immutable objects. If shouldComponentUpdate returns false, the component
and its sub-tree will not be re-rendered. This is very help when a child is not dependent on
its parent for state.

If React determines that it should render it will render a virtual DOM. React compares the
virtual DOM from the previous render with the current render to decide what has been
updated in the DOM. When comparing the old and new DOM React compares nodes in the
DOM tree. If it finds a node that doesn't have the same element or component type, it will
remove the old one including its entire sub-tree and replace it with the new one. This
provides a big gain in terms of performance because React doesn't have to waste time
tyring to reconcile sub-trees if the parent nodes don't match.

To help React efficiently compare nodes you should assign child elements a key attribute
with a value that is unique among its siblings elements. This makes it easier for React to
compare elements. React compares the attributes of elements to determine if there was a
change. If a change was found, only the attributes that have changed are updated.

It is much more efficient for React to work with the virtual DOM made of JavaScript objects
than say a browser DOM. You can read more about the heuristics React uses to reconcile
the DOM to make the minimum number of changes to a device's DOM

https://facebook.github.io/react/docs/reconciliation.html.

React Component Props and State


Props and state are both plain JavaScript objects that can be passed to a component to
provide the attributes of a component used to alter the behavior of the component and
render HTML. There are some suggestions regarding props and state to help keep your
application maintainable and easier to debug. These are only suggestions and there is
nothing in React that will prevent you from not following them. If you want your application to
be easier to reason about, I suggest you follow some guidelines to help make the state in
your application easier to maintain and debug.

React Component Props

React 45
Hello React and TypeScript

You can think of props as the components configuration or the external public API of the
component. Props are the external parameters that are passed into a component. Once
props are set don't expect them to stay in sync as the component goes through its lifecycle.
Within the component, props should be considered immutable or read only. After the
component is constructed props should not be changed. Parent components can pass props
to their child components. A component can set default values for props to keep default
values consistent when a props aren't passed in. Default props values will be overridden if
props are passed into the component.

React Component State


You can think of state as the private members of the component. State is only accessible
within the component, the parent cannot mutate state. State is an internal member of a
component. A parent can pass in props to set default values for state during construction of
the component. Components use state to enable interactivity. As event happen in the UI
state is updated and this causes the React to re-render the DOM with the new state. So,
state should only be used for a component's attributes that need to change over time. All
other attributes should be props.

React Component Communication and Data


Flow Rules
React components communicate by passing data. To make it easier to work with
components we impose rules that govern how components communicate. The rules can be
ignored because there are no mechanisms in React to enforce them, but adhering to some
rules makes your application easier to understand, maintain, and debug.

Handling State: MVC vs React


React is not MVC, it is a view engine. It is hard to compare it to something like Angular,
Ember or Backbone because they have fundamental differences. Because of these
differences you should handle data in React differently than you do in MVC.

In MVC you have mutable data or state in the form of models. Multiple views can depend on
a model. Changing a model could change multiple views. A view could change multiple
models. In large applications this many-to-many relationship can make it difficult to
understand what views depend on models and what models are updated from views.
Understanding how data flows and the state of the application over time can be a challenge.
The nature of the model view relationship also leads to funky circular dependencies that can
be ripe with hard to find bugs (like the well known issues with Global state).

React 46
Hello React and TypeScript

In React data or state is mutable, but it is private, not shared, and managed in components.
Because state is internal there are no side effects from shared state like MVC. When you
keep the number of stateful components low, it is easier to understand the state of your
application over time, hence easier to debug and maintain. We can use stateful components
to pass immutable properties to stateless components that will always be consistent with the
stateful component. When we know where, when, and how state changes and that
properties don't change once they are set there is a lot of guess work removed when we are
trying to debug or update our applications. By using the concept of stateful and stateless
components you can get a better handle on the state of your application at any point in time.

Stateful Components
A stateful component is a container that provides data or state service to stateless
components. They manage the state for itself and its child components. If we compare it to
DDD, a stateful component would be like an aggregate for a bounded context.

A stateful component maps its state to props that are passed down to stateless components
for consumption. The props are immutable and don't change once set and will always be
consistent with the stateful component that set them. Whenever state is updated (calling
this.setState ) the stateful component will render itself and all of its children, so children

stay consistent across re-renders.

A stateful component should handle events triggered by its children. Ideally, stateful
component wouldn't have props and would be able to compose its state on all its own,
independent of any parent or ancestors. It should be detached from its parent in terms of
rendering. It should only re-render when it has new state, not when it's parent re-renders. It
could possible use the shouldComponentUpdate to prevent re-rendering by parent.

shouldComponenUpdate(nextProps) {
return false;
//or return reference equality of immutable props
//return this.props === nextProps;
}

This is one way to prevent wasteful propagation of unnecessary renders.

For clarity I would recommend naming stateful components with a "Container" suffix so that
it is evident that it is a stateful component (e.g. MyFunkyContainer , MyFunkyTestContainer ).

Stateless Components

React 47
Hello React and TypeScript

Stateless components don't hold state and depend on their stateful parent component
container for state. The stateless component can trigger events that would cause the stateful
component to update state and therefore update the stateless component. Stateless
components are reusable and they aren't dependent on a specific stateful component
container, but requires a parent container to pass props.

It may be benefitial to code stateless components as React elements.

An element is a plain object describing what you want to appear on the screen in terms of
the DOM nodes or other components. Elements can contain other elements in their props.
Creating a React element is cheap. Once an element is created, it is never mutated.

Dan Abramov - http://facebook.github.io/react/blog/2015/12/18/react-components-elements-


and-instances.html

Element Example

const DeleteAccount = ({message, color, children}) => (


<div>
<p>Are you sure?</p>
<DangerButton>{message}</DangerButton>
<Button color='{color}'>Cancel</Button>
{Children}
</div>
);

Here we are creating an element named DeleteAccount with a simple JavaScript arrow
function. This can be composed in a parent component where the parent would pass the
props that are needed by the element (e.g. string message and color and child elements in
the example). This cuts down on code of a full component class when you don't need to use
state, lifecycle events, and other React component class features.

Jason Bonta of Facebook recommended an interesting test harness for stateless


components. You just build a mock or test container called an "explorer" with static data that
can be passed to stateless components for the purpose of testing. This sounds like a way to
cut down on difficult WebDriver tests to me.

Data Flow
Another way to look at the stateful-to-stateless component relationship is in terms of data
flow. Data is passed down the React component hierarchy in props (parent-to-child
communication). Props should be immutable because they are passed down every time

React 48
Hello React and TypeScript

higher components are re-rendered, so any changes in props would be loss on each re-
render. So, changing props after they are set is a good way to introduce bugs if you want
them, but why would you?

You can enforce props to be read-only in TypeScript by using a TypeScript property with only
a getter or in JavaScript ES5+ with object.defineProperty with writable set to false .
Defining props with persisted immutable data structure, like those found in immutable.js help
further in enforcing immutability and helps simplify comparisons when you need to compare
changes in props.

Event Flow
Events flow up the hierarchy and can be used to instruct higher components to update state
(child-to-parent communication). When you have components that need to communicate
that don't share a parent child relationship, you can write a global event system or even
better use a pattern such as Flux to enable cross component communication.

These flow rules allows us to easily visualize how data streams through our application.

Reference Equlity: The Holy Grail

React Component Lifecycle

React 49
Hello React and TypeScript

TypeScript

TypeScript Definition File References


To use external modules in TypeScript you should provide a definition of the types used in
the module. This will activate the IDE and the TypeScript compiler's ability to use these
types to help catch errors.

To use TypeScript typings in your code you have to provide a reference to the definition files.
This can be done with a reference
/// <reference path="someExternalModule.d.ts" />

If you modules are proper node modules, you should have to use a reference. If you have
problems importing a module that has a type definition, try including a reference to the type
definition.

I use tsd to import my type definitions. This creates a tsd.d.ts file that contains a reference to
all of the typings I have installed. I usually use this file as a reference instead of individually
listing each typing I want to reference.
/// <reference path="../typings/tsd.d.ts" />

This is a little of a maintenance issue because I am using relative paths and if I move the file
in the path heirarchy I have to update the reference path. There are ways to get around this
with a tsconfig file, but it is out of scope for this simple guide.

I have a lot of trouble with references and the internal module import system with TypeScript.
Using the reference and the root tsd.d.ts file has allowed me to use ES6 style import with
little friction, but it took me some searching to get over some nuances that aren't apparent.

Importing Modules
To get the strong typing in TypeScript it has to know about the types you will be using. You
can define your custom types as you build up your application, but if you are using third
party modules like React, you have to give TypeScript some help.

Import External Modules

TypeScript 50
Hello React and TypeScript

To import an external module, like a node module, you just use the name of the module
instead of the path. TypeScript is smart enough to search in common locations for the
module.

import SomeModule from ('some-external-module'); //import the default module


import * SomeModule from ('some-external-module'); //import all exports from the module
import {someExportA, someExportB as SomeModuelB } from ('some-external-module'); //import specific mo

Import Internal Modules


To import an internal module that you exported you need to import from a relative path (you
can use a tsconfig file to get around relative paths). For example, if I exported a module
named somemodule in a root folder named js, then I would import it like so.

import SomeModule from ('./js/somemodule'); //import the default module


import * SomeModule from ('./js/somemodule'); //import all exports from the module
import {someExportA, someExportB as SomeModuelB } from ('./js/somemodule'); //import specific moduels

You can read more about importing modules at https://developer.mozilla.org/en-


US/docs/Web/JavaScript/Reference/Statements/import.

You can read more about tsconfig file at https://github.com/TypeStrong/atom-


typescript/blob/master/docs/tsconfig.md

TypeScript 51
Hello React and TypeScript

TypeScript and React

TypeScript React Component


With TypeScript we extend the React.Component<P,S> class to create React components.
You also define the type used for props and state by passing the expected types as <P,S> .

Below we have an example where we are exporting a component. Since there can be more
than one component in a namespace we mark our default component with the default
keyword. Even if there are no other components, setting default makes it easier to import the
component without having to define the default in the import statement.

Since the example doesn't use props or state and we haven't created types for them we
pass in any to let the IDE and TypeScript compiler know that any type is acceptable for
props and state. If we wanted to use props and state, we would create an interface to define
the type we are expecting.

export default class MyComponent extends React.Component<{}, {}> {


public render() {
return (
<div>
Hello World!
</div>
);
}
}

This is just a simple guide, so any deeper is out of scope. If you would like to get more info
on React Components in TypeScript, I suggest taking a look at the type definition at
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/react/react.d.ts. Unless the
signature has changed, you can do a search for type ReactInstance = Component<any, any> |
Element; to get a feel for how the type is constructed and what properties and methods are

available.

TypeScript React Component Props and State


Below we are using props to set a default value for a state value and then using the state
value to render in the UI. When using TypeScript for React we define interfaces for the props
and state objects. You can see this in the example, IMyComponentProps and

TypeScript and React 52


Hello React and TypeScript

IMyComponentState are interfaces that define the types these objects should contain. If your
IDE support TypeScript it may be able to use these interfaces to give you visual feedback
when you have the wrong types. The TypeScript compiler will also use the interfaces to do
type checking. You can get a similar effect in normal React by using propTypes, but I enjoy
how TypeScript maps to my C# OOP braint, it makes the component cleaner and easier to
read in my opinion.

interface IMyComponentProps {
someDefaultValue: string
}

interface IMyComponentState {
someValue: string
}

export default class MyComponent extends React.Component<IMyComponentProps, IMyComponentState


constructor(props : IMyComponentProps) {
super(props);
this.state = { someValue: this.props.someDefaultValue };
}

public render() {
return (
<div>
Value set as {this.state.someValue}
</div>
);
}
}

This example is assuming that someValue may get changed over time because it is in a
state object (we aren't showing the code that would change the state to keep the code
simple). If we know that someValue won't change during the components lifetime we would
just use the props values directly in render ( Value set as {this.props.someDefaultValue} ).
Since props are immutable and shouldn't change, we only move props to state in the
constructor when we know the values will change.

TypeScript and React 53


Hello React and TypeScript

References
1. React Documentation by Facebook - https://facebook.github.io/react/docs/getting-
started.html
2. React’s diff algorithm by Christopher Chedeau - http://calendar.perfplanet.com/2013/diff/
3. React.js Conf 2015 by Facebook - https://www.youtube.com/playlist?list=PLb0IAmt7-
GS1cbw4qonlQztYV1TAW0sCr
4. TypeScript Handbook by Microsoft - http://www.typescriptlang.org/Handbook
5. TypeScript Deep Dive by Basarat Ali Syed - https://basarat.gitbooks.io/typescript/

References 54
Hello React and TypeScript

Glossary

CQRS
Command Query Responsibility Segregation

1.6. Accept User Input

DAG
[Directed acyclic graph - https://en.wikipedia.org/wiki/Directed_acyclic_graph]
(https://en.wikipedia.org/wiki/Directed_acyclic_graph)

3. React

DDD
Domain Driven Design

3. React

DOM
Document object model.

3. React 2.2. Package Management 1.2. Component Basics


1.7. Component Composition 1.4. Component Props and State
1.3. Components in Separate Files

MVC
Model View Controller.

3. React 1.6. Accept User Input

Glossary 55
Hello React and TypeScript

UDF
Unidirectional Data Flow

1.6. Accept User Input

UI
User interface.

3. React 2.2. Package Management 1.7. Component Composition


1.4. Component Props and State 5. TypeScript and React

Glossary 56

You might also like