Author avatar

Matt Ferderer

Building React Stateless Functional Components with TypeScript

Matt Ferderer

  • Mar 1, 2019
  • 5 Min read
  • 21,887 Views
  • Mar 1, 2019
  • 5 Min read
  • 21,887 Views
React
Typescript

Introduction

Stateless functional components are an awesome way to decouple complex architecture from the design of a component's output. You can remove the unnecessary bloat of complex logic and provide a simple presentational component that is easy to read and re-use. This opens the doors for more people to help with development and adding types with TypeScript makes it even easier!

How to Declare a Stateless Functional Component in TypeScript

One way to declare a Stateless Functional Component in React is to create a function that takes a Props like below:

1
2
3
4
5
export function Example(Props: ExampleProps) {
    return (
        <div />
    )
}
tsx

While this works, you do miss out on some additional type information.

Prior to React 16.8, you could declare a React Stateless Functional Component in TypeScript as either a React.SFC or React.StatelessComponent.

1
2
3
4
5
6
7
8
9
10
11
export const ExampleA: React.SFC<CardProps> = (props) => {
    return (
        <div />
    )
}

export const ExampleB: React.StatelessComponent<CardProps> = (props) => {
    return (
        <div />
    )
}
tsx

As of 16.8, both these types have been deprecated due to the introduction of Hooks. Function components can no longer be considered stateless with the introduction of hooks. That doesn't mean we can't or shouldn't create a Stateless Functional Component though. Just like React class components, whether the component has a state or not is still up to us.

The latest React TypeScript definition gives you the choice between the following two new identical types.

1
2
3
4
5
6
7
8
9
10
11
export const ExampleA: React.FC<CardProps> = (props) => {
    return (
        <div />
    )
}

export const ExampleA: React.FunctionComponent<CardProps> = (props) => {
    return (
        <div />
    )
}
tsx

So as not to break existing code, SFC and StatelessComponents are now aliases for React.FunctionComponent. They also give a heads up deprecated warning message.

Now, let's take this and build out a real Stateless Functional Component.

Building a Simple Card Component

A popular component in many CSS frameworks, like Bootstrap and Foundation, is the Card Component. It takes a title, image, and a message. In this example, we're going to look at building a Simple Card Component using stateless function components in React. To make the component easier to use in other components, we will add TypeScript definitions to our properties.

Here's how we can build our Card Component with TypeScript in React.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import * as React from "react";

interface CardProps {
    Title: string
    Image: string
    Body: string
}

export const Card: React.FC<CardProps> =
    ({ Title, Image, Body }) => (
        <div className="card">
            <div className="title">{Title}</div>
            <div className="image">
                <img src={Image} />
            </div>
            <div className="body">{Body}</div>
        </div>
    )
tsx

From here, you can add additional complexity at the cost of readability. For example, you could make your Image property optional.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import * as React from "react";

interface CardProps {
    Title: string
    Image?: string
    Body: string
}

export const Card: React.FC<CardProps> =
    ({ Title, Image, Body }) => (
        <div className="card">
            <div className="title">{Title}</div>
            {Image &&
                <div className="image">
                    <img src={Image} />
                </div>
            }
            <div className="body">{Body}</div>
        </div>
    )
tsx

If you are wondering what the {Title, Image, Body} does, I highly encourage you to check out destructuring. In short, it maps the values of the CardProps object we pass into new variables that have the same name. It's a nice way to avoid having to type Props.Title and write Title instead.

Summary

I am a huge fan of creating at least one Stateless Functional Component for each React component that has a state. Not only does this allow you to test your components separately, but it also increases the usability of common component types. If you work in larger teams, stateless functional components can increase the ease in which designers and other developers can work with your code. They no longer need to understand much about React or modern JavaScript.

A popular pattern that I often use is to build stateless functional components in Storybook with the application's designers. We can collaborate and quickly iterate on simple components which I can then re-use with stateful components elsewhere.

To learn more about TypeScript check out TypeScript Fundamentals and Advanced TypeScript. For more on React, try out the awesome React Path and see where your skill is at.

About the Author

Matt Ferderer is a software developer who tweets, posts and blogs about web development.

41