May 10, 2018

Introduction to React with Typescript

Background

React is the most popular Javascript (JS) library for building user interfaces from Facebook.

Unlike Angular, React is a library for the UI only; it does not comes with other common tools for a frontend application, e.g. state management, routing, and ajax call.

Why Typescript

One of the thing that React do not mandate is static typechecking system.

As JS is a weakly typed language, static typechecking system is introduced into JS application as it can catch a lot error during compile time, which is cheaper and easier to fix than runtime error.

The 2 most common static typechecking system to be used with React are:

  • Flow (from Facebook as well) and
  • Typescript.

Even though Flow is used by Facebook internally for their React applications (thus theoretically they should work together better than Typescript), but Typescript support for React is very good as well except for some edge cases.

For a developer that has previous experience in Typescript (probably with Angular), using Typescript is a better option because you can utilize your previous knowledge.

Setting Up

Setting up the application to use React with Typescript requires configuration of webpack, babel, and typescript. If you like to learn about them, you can refer to this Medium article.

If you just want to get started and start coding, I would recommend create-react-app.

Run the following commands in your command prompt (after you’ve installed node.js with npm):

sh
npx create-react-app my-app-name --typescript
cd my-app-name
npm start
sh
npx create-react-app my-app-name --typescript
cd my-app-name
npm start

How to Type Props

Props is the “input” to a React component from the parent to control it. If you do not know what is props, read this section of React docs before continue.

Type Props for Stateless Functional Component

Take a Profile component that shows username and email address as an example:

jsx
import * as React from 'react';
export const Profile = props => {
return (
<div>
<h1>{props.username}<h1>
<p>{props.email}</p>
</div>
);
};
jsx
import * as React from 'react';
export const Profile = props => {
return (
<div>
<h1>{props.username}<h1>
<p>{props.email}</p>
</div>
);
};

Creating similar version in typescript with typing for the props would be:

ts
import * as React from 'react';
interface ProfileProps {
username: string;
email: string;
}
export const Profile: React.SFC<ProfileProps> = props => {
return (
<div>
<h1>{props.username}<h1>
<p>{props.email}</p>
</div>
);
};
ts
import * as React from 'react';
interface ProfileProps {
username: string;
email: string;
}
export const Profile: React.SFC<ProfileProps> = props => {
return (
<div>
<h1>{props.username}<h1>
<p>{props.email}</p>
</div>
);
};

Note that:

  • The import statement for React in Typescript should be in the format of * as React.

Type Props for Class Component

Reusing the previous Profile example, but making it as Class Component:

jsx
export class Profile extends React.Component{
render() {
return (
<div>
<h1>{this.props.username}<h1>
<p>{this.props.email}</p>
</div>
);
}
}
jsx
export class Profile extends React.Component{
render() {
return (
<div>
<h1>{this.props.username}<h1>
<p>{this.props.email}</p>
</div>
);
}
}

Typescript version:

ts
interface ProfileProps {
username: string;
email: string;
}
export class Profile extends React.Component<ProfileProps>{
render() {
return (
<div>
<h1>{this.props.username}<h1>
<p>{this.props.email}</p>
</div>
);
}
}
ts
interface ProfileProps {
username: string;
email: string;
}
export class Profile extends React.Component<ProfileProps>{
render() {
return (
<div>
<h1>{this.props.username}<h1>
<p>{this.props.email}</p>
</div>
);
}
}

How to Type State

State is any arbitrary data that you would like to track as part of your component, e.g. a checkbox has a state to tracked if it is ticked, or a toggler to track if it is toggled etc. You can read more about state here.

Type State for Class Component

Only Class Component can has its own state.

Using a button that use the label on it to indicate its current status:

jsx
export class Button extends React.Component {
state = {
on: false,
};
handleToggleOn = () => {
this.setState((prevState) => ({
on: !prevState.on,
}));
};
render() {
return <button onClick={this.handleToggleOn}>{this.state.on ? 'On' : 'Off'}</button>;
}
}
jsx
export class Button extends React.Component {
state = {
on: false,
};
handleToggleOn = () => {
this.setState((prevState) => ({
on: !prevState.on,
}));
};
render() {
return <button onClick={this.handleToggleOn}>{this.state.on ? 'On' : 'Off'}</button>;
}
}

Including typing of the state in Typescript version:

ts
interface ButtonState {
on: boolean;
}
export class Button extends React.Component<{}, ButtonState> {
state: ButtonState = {
on: false,
};
handleToggleOn = () => {
this.setState((prevState) => ({
on: !prevState.on,
}));
};
render() {
return <button onClick={this.handleToggleOn}>{this.state.on ? 'On' : 'Off'}</button>;
}
}
ts
interface ButtonState {
on: boolean;
}
export class Button extends React.Component<{}, ButtonState> {
state: ButtonState = {
on: false,
};
handleToggleOn = () => {
this.setState((prevState) => ({
on: !prevState.on,
}));
};
render() {
return <button onClick={this.handleToggleOn}>{this.state.on ? 'On' : 'Off'}</button>;
}
}

That’s it!

Further Readings


If you’re a ReactJS developer or interested to learn React, come join my Meetup group.

Thanks for reading!

Love what you're reading? Sign up for my newsletter and stay up-to-date with my latest contents and projects.

    I won't send you spam or use it for other purposes.

    Unsubscribe at any time.