Learning React - Exercise control over your component state with Typescript

July 12, 2018 · 4 minute read · Tags: react

The last post 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.

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

    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.

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.

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…

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

export interface IState {
    users: IUser[];
}

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

Then we can declare our component state’s type…

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

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

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!

Looking to get up and running with React?

All you need is a little nudge in the right direction.

Pop your email in the box below and I'll ping over a link to the subscribers only vault which includes my React + ASP.NET quickstart course; discover how to build any React component and hook it up to an ASP.NET Core backend.

I respect your email privacy. Unsubscribe with one click.

    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.

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

    Set it to false for starters.

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

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

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

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

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

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

    The result would be ‘It’s Sunday’.

    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

    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.

    photo credit: Pranav Bhatt Sign, Southern Africa via photopin (license)

    Join the Practical ASP.NET Newsletter

    Ship better Blazor apps, faster. One practical tip every Tuesday.

    I respect your email privacy. Unsubscribe with one click.

      Next up

      Edit and Replay your network requests, direct from the browser
      Half the battle with building a client-side web app (using Blazor, React etc) is figuring out what calls are being made to the network. Now you can see but also edit those requests and replay them…
      Quickly transform any mockup or design into a working Blazor prototype
      Even complicated applications can be broken down into small components, making them much less daunting to build.
      But, which flavor of ASP.NET?
      Blazor, Razor, MVC… what does it all mean?!