Tagged: react.js

Part 7: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

Component Composition

https://charleslbryant.gitbooks.io/hello-react-and-typescript/content/Samples/ComponentComposition.html

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>
        );
    }
}

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 name of the component.


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 HelloContentcomponents. 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.

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

/// <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.

Part 6: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

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.


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.

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 UDFin 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.

Part 5: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

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

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 callthis.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 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 thehandleOnClick 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.

Part 3: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

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';

 

We added a new import to import the HelloWorld component.


 

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

/// <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.

Part 1 & 2: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

If you haven’t heard, I have been writing a little book called “Hello React and TypeScript“. Its a simple book that chronicles the steps I took to learn how to develop a React application using TypeScript and ES6.

I’m going to post some of the chapters here on my blog. This will provide an easy reference for me because the chapters are really a reorganization of notes that I took as I learned writing React with TypeScript/ES6. It is my hope that these posts may be helpful for someone looking to learn.

I will post the chapters, but I won’t keep them in sync with the book. If you want the latest and greatest, please check out the free book.


To start this series off we will look at the code samples. In this first post we will look at two chapters: Setting Up Samples and Component Basics. If you haven’t used React or TypeScript, I recommend you actually try out the code to get a better feel for React and TypeScript. You can reach out to me in the comments below or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.


Setting Up Samples

https://charleslbryant.gitbooks.io/hello-react-and-typescript/content/SettingUpSamples.html

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 changes are made to source files.

Basic React Component

https://charleslbryant.gitbooks.io/hello-react-and-typescript/content/Samples/ComponentBasic.html

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

. We will tell React to inject its HTML output to this div.

src/main.tsx

/// <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';

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 athttps://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.

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.

Recent Talks with Big Effect on My Development

I have seen many, many development talks, actually an embarrassing amount. There have been many talks that have altered how I develop or think about development. Actually, since 2013, some talks have caused a major shift in how I think about full stack development, my mind has been in a major evolutionary cycle.

CQRS and Event Sourcing

My thought process about full stack development started down a new path when I attended Code on the Beach 2013. I watched a talk by Greg Young that included Event Sourcing, mind ignited.

Greg Young – Polyglot Data – Code on the Beach 2013

He actually followed this up at Code on the Beach 2014 with a talk on CQRS and Event Sourcing.


Reactive Functional Programming

Then I was introduced to React.js and I experience a fundamental paradigm shift in how I believed application UIs should be built and began exploring reactive functional programming. I watched a talk by Pete Hunt where he introduced the design decisions behind React, mind blown.

Pete Hunt – React, Rethinking Best Practices – JSConf Asia 2013


Stream Processing

Then my thoughts on how to manage data flow through my applications was significantly altered. I watched a talk by Martin Kleppmann that promoted subscribe/notify models and stream processing and I learned more about databases than any talk before it, mind reconfigured.

Martin Kleppmann – Turning the database inside-out with Apache Samza – Strange Loop 2014


Immutable Data Structures

Then my thoughts on immutable state was refined and I went in search of knowledge on immutable data structures and their uses. I watched a talk by Lee Bryon on immutable state, mind rebuilt.

Lee Bryon – Immutable Data in React – React.js Conf 2015


Conclusion

I have been doing professional application development since 2000. There was a lot burned into my mind in terms of development, but these talks where able to cut through the internal program of my mind to teach this old dog some new tricks. The funny thing is all of these talks are based on old concepts from computer science and our profession that I never had the opportunity of learning.

The point is, keep learning and don’t accept best practices as the only or best truth.

 

My New Book: “Hello React and TypeScript”

So, I have been doing a deep dive into React and TypeScript and found it a little difficult to find resources to help me. I could find plenty of great resources on React and TypeScript separately. Just exploring the documentation and many blogs and videos for the two is great. Yet, resources that explore writing React applications with TypeScript was either old, incomplete, or just didn’t work for me for one reason or another. I have to admit that I haven’t done a deep search in a while so that may have changed.

After some frustration and keyboard pounding, I decided to just consume as much as I can about both individually and just get a Hello World example working. With the basics done I went slowly all the way to a full blown application. Since I was keeping notes on that journey, why not share them?

I was going to share them in a few blog posts, but I have been trying to do a book on GitBook for a while and this topic seemed like a good fit. Also, I enjoy digging into React and TypeScript so this book is probably something I can commit to, not like my other sorry book attempts.

My little guide book isn’t complete and still very rough. It may not be completed any time soon with the rapid pace of change for JavaScript, TypeScript and React. Also, I am thinking about moving from Gulp/Browserify to WebPack. I have only completed a fraction of the samples I want to do… so much still to do. Even though I don’t think it is ready for prime time, it is a public open source book so why not share it, get feedback, and iterate.

You can get the free book from GitBook

https://charleslbryant.gitbooks.io/hello-react-and-typescript/content/index.html

The source code for the samples in the book are on GitHub

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

If you don’t like the book let me know. If you find something wrong, bad practice or advice, incoherent explanations… whatever, let me know. If you like it let me know too, I can always use an ego boost :). Now I just have to convince myself to do some videos and talks… public speaking, bah :{

Enjoy!