Way of the Script — React + Redux + Typescript: Part 1 — Introduction

Hail,
This will be my first ever posted article, so I would like to warn you in advance that I may yet much to learn when it comes to my blog writing style, you may find it weird, strange, and plain silly, but I guarantee you will gain some insight ;).

My girlfriend and I (Dev couples are awesome, all devs should all have this privilege :D) have been using React JS, and its eco-system (Redux, Redux-Thunk / Sagas, React Router…the list goes on), for quite some time now and have gained sufficient knowledge that would please even the Gods of Valhalla themselves.

Source: https://thevikingsnorsegods.wikispaces.com/Odin

Recently for R&D at work I was tasked to research into Typescript with React JS which I found simple enough, but when I threw Redux into the mix, coupled with an application structure which went further than a Counter example, and more “production ready”, I began to struggle to get things to work correctly, due to lack of updated articles, or other samples application structure was not something which I was looking for.

I decided to create a warriors manual, and hopefully save other people like me a huge headache (maybe a few hairs on their head also), and put together a series of guides. I am extremely new to Typescript, having only used it for just over a week, so I have much more to learn, but I believe I what I currently have to share may be beneficial for others.

Please note this is not a guide for beginners that are not familiar with the concept of React, Redux etc. The Webpack configuration will also not be explained and it will be kept very simple as it is not the basis of this article. Though if I gain positive feedback I could also write an article with an introduction to React/Redux/Sagas and Webpack to provide a guide for beginners.

This article will be broken into multiple parts, starting off with a basic counter application with Typescript, slowly gaining more complexity, and the project structure will also evolve over time.

Guides

Project Setup

My github repository has a starter project which you can clone to follow along with this guide, I will have a “start” and “finished” project for each part of this guide for reference.

  • Clone the starter project from the following: git clone git@github.com:xXValhallaCoderXx/01-Medium-Blog-React-Redux-Typescript-Tutorial.git
  • Install npm module: npm install or yarn install
  • Run the project: npm start or yarn start it will be running on localhost:8080

Exploring Project Files

The majority of our application is pretty standard at this point, and there won’t be anything “new” to throw you off guard, so I will just briefly describe some of core differences.

Here is where our configuration is setup for the TS compiler, We are still going to use webpack to do the bulk of the work when it comes to transpiling our code into “browser friendly” javascript (is there even such a thing? o.O). This config file has a huge amount of settings which we can use to customize, that can be found here.

Note: You may see in other examples people handle their imports in this manner:

import * as React from 'react

By setting allowSyntheticDefaultImports this allows us to import in a much more familiar way such as:

import React from 'react

./src/components

Here is our Typescript component! As you can see currently it doesn't look that much different from our normal React class components, except for a few minor alterations.

interface: This is something you will hear about a lot in the world of Typescript, to keep things simple we can say that interfaces act as a “blueprint” or a “model” of what our application State or Props will be.

export class HelloWorld extends React.Component<HelloWorldProps>: In-between the two arrows you can pass 2 objects which are React.Component<{Props},{State}>, which allows us to add type checking to our Component, so it can know what props and pieces of state to allow.

If we look into ./src/index.tsx, we can see that we are passing in the following prop:

name="Valhalla Coder"

If we were to change the Interface of Hello.tsx and changed HelloWorldProps to the following, while the application was running:

interface HelloWorldProps {
name: number;
}

The Typescript compiler would instantly throw an error message stating:

Types of property ‘name’ are incompatible. Type ‘“Valhalla Coder”’ is not assignable to type ‘number’.

Which is our first piece of awesomeness that we get to taste, with minimal boilerplate we are already able to reap the rewards of Typescript, though our path is long a hardy yet till we are worth to enter the Halls of Valhalla, for we have yet much to learn.

Creating our first component

As we are on our way to becoming Type wielding warriors, lets create our first component, create a file named Stateless in the following directory: ./src/components/Stateless.tsx

import React from "react";export interface StatelessPropTypes {
norseGod: string;
numberOfSons: number;
}
const Ode = ({ norseGod, numberOfSons}: StatelessPropTypes) => (
<div>
<h4>{norseGod} The Wanderer</h4>
<div>Has {numberOfSons} Sons</div>
</div>
);
export default Ode;

Now if we were to import this Stateless component into our Hello.tsx file, be ready for the blinding light of awesomeness that Typescript brings to the table.

If we define the Stateless.tsx component in our Hello.tsx component without passing in any props, again Typescript will instantly throw an error and also display a red squiggly line of goodness under your component to let you know that something is not quite up to scratch.

Type '{}' is not assignable to type 'StatelessPropTypes'.
Property 'norseGod' is missing in type '{}'.

So we are instantly alerted that our component named Stateless.tsx is expecting some data. I hope you’re ready for this, as thing are yet to get even more awesome. I am not sure what the shortcut is on other IDE’s, but on VS Code, while I am entering props in the component, if you press Ctrl + Space, Typescript and our editor will instantly tell us, what props this component is expecting, and what data types they are, without us even needing us to check the component itself!

So if we now pass in the correct props to our Stateless.tsx component:

<Stateless norseGod="Odin" numberOfSons={4} />

everything should render as normal, and our application should render in the browser once again.

It doesnt look pretty, but this aint no UX tutorial :D

I encourage you to have a little play around at this point, with different types, also try passing incorrect prop types to the Stateless.tsx component so you can start getting a feel, for the errors thrown by the Typescript compiler.

Props are cool, but what about State?!

Ahhh our fabled application state, where would we be without it? Ever since I started developing in React, it completely changed the web development game for me. As much as I hate Javascript, at the same time its extremly fun to code in (once you get past the hundreds of different choices we need to make to setup our applications :D )

So in our Hello.tsx component, we will now create a new interface for our component state, bellow the HelloWordProps interface, lets define another called…. HelloWorldState

N.B. I found it useful to append interfaces with the word Props or State to help us easily manage our applications, but you can call them or have what ever naming style you prefer :).

interface HelloWorldState {
componentState: number;
}

We also need to add the State object to where we define our Hello.tsx component, so it should look like the following:

class HelloWorld extends React.Component<HelloWorldProps, HelloWorldState> {

Next we need to define our constructor for the component, just like we do with normal JS, though this time you will get an error.

constructor(props) {
super(props);
this.state = {
componentState: 100,
};
}

Typescript will complain about props stating:

Cannot find name 'props'. Did you mean the instance member 'this.props'?

If we changed the props argument in the constructor to:

We are given a more useful error, and Typescript is complaining because it does not know what “shape” it should expect the component props to be.

A quick solution to this would be to define its type as ‘any’, like so:

Why would we want to do this though?!

While this is a quick and easy fix, we are loosing why we went through all the hassle in the first place of setting up Typescript….. Type checking! So we want to avoid having to use ‘any’ as our type as much as possible.

N.B. This may come handy at times when you are migrating a JS application over to TS, so you can have an easier time slowly migrating and refactoring.

What we want to do here, is pass our HelloWorldProps interface as the type for props in our constructor, to satisfy the requirements for the type checking.

Good bye errors, Hello Types!

Since we had already passed our HelloWorldState interface to the component, if we were to intilize another piece of state in the constructor, the Typescript compiler would instantly alert us, as it doesnt match the HelloWorldState interface we defined

Types of property 'componentState' are incompatible.
Type 'string' is not assignable to type 'number'.

If we also instantiated the componentState variable in the constructor as a string, once again the Typescript compiler would scream at us for doing something incorrectly.

The freedom of JS is gone :( but at least us devs will have less headaches :D

This section has already started to become quite lengthy, so I will start to wrap things up, as I would rather spread this series over multiple bite sized chunks for us to digest.

I hope through this basic example, you can begin to understand the benefits that Typescript can bring to us React developers, and how it can save us a huge pain in the future when we build larger applications. Further along our path to Valhalla, we shall slowly morph our application into something so worthy, that even Thor himself, will beat his hammer in glory.

If anything was unclear, here is the source code for the end result of this application: https://github.com/xXValhallaCoderXx/01-Medium-Blog-React-Redux-Typescript-Tutorial/tree/01-Introduction-End

So I would like to say, thank you for giving me your attention span for this long, and also for putting up with my writing style, I still have much to learn when it comes to this. If you have enjoyed the article, or have any feedback, please do let me know!

Till then my brothers and sisters, hold thy hammer high!

Source: https://images.moviepilot.com/image/upload/c_fill,h_470,q_auto:good,w_620/thor-hammer-physicist-provides-solid-scientific-explanation-for-thor-s-magical-hammer-jpeg-178660.jpg