Learning React - Exercise control over your component state with Typescript
Tags: react, aspnetcore, webapi
Published: 2018-08-23 08:54:32

---
title: Learning React - Exercise control over your component state with Typescript
published: true
description: Use Typescript to define the shape of your React component's state 
tags: react, aspnetcore, webapi
canonical_url: https://jonhilton.net/react-component-state-using-typescript/
cover_image: https://jonhilton.net/img/diary-of-a-net-developer-part-4/wild_animals.jpg
---

The [last post](https://dev.to/jonhilt/learning-react---how-to-connect-react-components-to-your-aspnet-core-web-api-1jl) left us with a bit of a problem.

Although our user component retrieves and displays data from ASP.NET API, it also flashes up some hard-coded data before the real data shows up.

![](https://jonhilton.net/img/diary-of-a-net-developer-part-3/ReactFlicker.gif)

It seems like we could just remove the hard-coded data so let's try that...

``` javascript
    public state = {
        "users": []
    };
```

Seems reasonable, except for one problem, it doesn't compile.

Yes that's right, javascript gets compiled these days! And in this case we run into an error.

![](https://jonhilton.net/img/diary-of-a-net-developer-part-4/2018-07-12-16-12-50.png)

This seems odd at first, it was working before.

Turns out, when we had our hard-coded data, Typescript was able to infer the type from the structure of this data.

``` javascript
public state = {
    "users": [
        { "id": 1, "name": "Jon Hilton", "summary": "36 / Lead Developer" },
        { "id": 2, "name": "Janine Smith", "summary": "32 /  Senior Engineer" }
    ]
};
```

So, because that data included an id property, everything "just worked".

Now we don't have any data, there's nothing for the compiler to go off, so it blows up when it comes to this line...

``` javascript
{this.state.users.map(user => <UserRow key={user.id} user={user} />)}
```

Turns out, this isn't a problem if we stop being lazy and actually define types for our state.

``` javascript
export interface IState {
    users: IUser[];
}

export interface IUser {
    id: number,
    name: string,
    summary: string
}
```

Then we can declare our component state's type...

``` javascript
export default class MyUsers extends React.Component<any, IState>{
```

And finally, tweak the code where we set the initial state (to indicate the type).

``` javascript
public state: IState = {
    "users": []
};
```

Now everything compiles, plus we have the benefit that we've removed the ambiguity about our state. 

You'll get proper intellisense in Visual Studio Code and there's less uncertainty all round!

**Just before we continue, if you fancy a gander at the source code for this series [grab it here :-)](https://jonhilton.net/devto/react-source/)**

## Loading...

This has removed our flash of data, but what if we want to show a loading indicator when the data's being retrieved?

We need a way to render different content if we're loading data, then show the list once the data's available.

As with all things in React, if we can change the underlying state as we're making the API call, the user interface can react to that and show a loading indicator of some kind.

We can add a `loading` boolean to IState.

``` javascript
export interface IState {
    loading: boolean;
    users: IUser[];
}
```

Set it to false for starters.

``` javascript
public state: IState = {
    loading: false,
    "users": []        
};
```

Then flip this flag when we're loading data from the back-end.

``` javascript
public async componentDidMount() {
    this.setState({ loading: true }); // toggle on
    const result = await fetch('https://localhost:44348/api/user');
    const users = await result.json();
    this.setState({ users, loading: false }); // toggle off
}
```

And finally make our html react to this and render some kind of loading indicator (when `state.loading` is true).

``` html
<h1>My Users</h1>
{this.state.loading && <div>Loading...</div>} // add this
<table className="user-list">
    <tbody>
        {this.state.users.map(user => <UserRow key={user.id} user={user} />)}
    </tbody>
</table>
```

This looks a bit weird the first time you see it so let's break it down.

``` javascript
{this.state.loading && <div>Loading...</div>}
```
This will show the Loading div if `this.state.loading` evaluates to true.

As a C# developer you'll be used to the more classic `if` statement.

So what is this `&&` madness?!

Turns out, in javascript, the `&&` logical operator returns the value of one of the specified operands.

If you have an expression like this.

``` javascript
const isSunday = true;
const result = isSunday && 'It\'s Sunday';
```

The result would be 'It's Sunday'.

``` javascript
const isSunday = false;
const result = isSunday && 'It\'s Sunday';
```

And this would return false!

The table over here explains this much better than I'd hope to!

[Javascript Logical Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators)

![](https://jonhilton.net/img/diary-of-a-net-developer-part-4/2018-07-12-17-03-51.png)

So in the end, this is just a concise way of saying "show the loading indicator if `this.state.loading` is true".

## Your state is typed!

Whilst it's tempting to throw `any` around all over the place to avoid declaring types, this shortcut ultimately makes some things more difficult and removes the benefits of using Typescript in the first place.

Create your types, use conditional rendering and your components will react in a predictable way, based purely on the underlying state of the component.

**Remember, if you fancy a gander at the source code for this series, you can [grab it here :-)](https://jonhilton.net/devto/react-source/)**

*photo credit: Pranav Bhatt <a href="http://www.flickr.com/photos/58403098@N08/39463590482">Sign, Southern Africa</a> via <a href="http://photopin.com">photopin</a> <a href="https://creativecommons.org/licenses/by-nc-sa/2.0/">(license)</a>*