Author avatar

Deeksha Sharma

Render a React Component with State and Props using TypeScript

Deeksha Sharma

  • Jul 3, 2020
  • 7 Min read
  • 44,538 Views
  • Jul 3, 2020
  • 7 Min read
  • 44,538 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

Writing components in TypeScript that contain both props as well as a state is one of the core tasks needed to build apps. Though both Functional and Class Components can contain props and a state, this guide will cover how to create and render a Class Component.
This is useful when migrating the React Class Components to TypeScript or writing them from scratch.

Use Case

Consider a web page that displays famous quotes on the screen and a button that renders a new quote when clicked. This functionality requires a component to have both props and state. A collection of quotes will be passed in props and state. The component tracks the current quote being displayed on the screen.

Set Up a React TypeScript App

Open your terminal and run these commands to get a sample TypeScript app running on your machine.

1npx create-react-app my-app --template typescript
2cd my-app
3yarn start
bash

To run the app in development mode, open http://localhost:3000 in your browser. You should see the sample TypeScript app running.

Add QuoteApp Component

Delete the App.tsx file inside your src directory. Now create a new component src/QuoteApp.tsx and add the code below.

1import React from 'react';
2import './App.css';
3
4type QuoteProps = {
5    quotes: string[]
6}
7
8type QuoteState = {
9    currentIndex: number,
10}
11
12export default class QuoteApp extends React.Component<QuoteProps, QuoteState> {
13
14    render() {
15        return <div className="App">
16            <header className="App-header">
17                <h3>Render Component with State and Props using TypeScript</h3>
18            </header>
19        </div>
20    }
21}
tsx

In the code above, <QuoteApp> is a Class Component and in TypeScript, React.Component is defined as a generic type with two optional type parameters. The first one is for prop type and the second for the state type.

QuoteProps is the type defined for the props allowed in the <QuoteApp> component. The caller of the <QuoteApp> component should pass an array of strings in props containing the quotes to display. QuoteState is the type defined for the state of the <QuoteApp> component. It contains the currentIndex of type number. This is the current index of the quote being rendered from the collection. Inside the render() function a <div> is returned that displays a header on the web page with the header text rendered inside an <h3> element.

Render Component Using State and Props

It's time to display the quote on the web page and a button so that users can click on it. The code below would do the job. The <QuoteApp> component has a state of type QuoteState with an initial value for currentIndex as zero. When the component is called with props quotes (an array of strings), the quoteToDisplay variable gets the element at currentIndex from that array and renders it. The <div> element contains inline styles to give it an appropriate alignment and the quote is displayed inside an HTML heading, <h4>.

A <button> is added with a label "NEXT QUOTE". When user clicks on this button, the getNextQuote() function is called. It returns void and update the state with a new value of currentIndex. It also calls getIndex() function whose job is to return a random number between zero and the last index of the quotes array.

In a nutshell, when a user clicks on the NEXT QUOTE button, the getNextQuote() function gets a new value for the index by calling getIndex() function. Once the currentIndex value is updated, the quote at that index is rendered.

1import React from 'react';
2import './App.css';
3
4type QuoteProps = {
5    quotes: string[]
6}
7
8type QuoteState = {
9    currentIndex: number,
10}
11
12export default class QuoteApp extends React.Component<QuoteProps, QuoteState> {
13    state: QuoteState = {
14        currentIndex: 0,
15    };
16
17    getIndex = (): number => {
18        const min: number = 0;
19        const max: number = this.props.quotes.length - 1;
20        return Math.floor(Math.random() * (max - min) + min);
21    };
22
23    getNextQuote = (): void => this.setState(state => ({currentIndex: this.getIndex()}));
24
25    render() {
26        const quoteToDisplay = this.props.quotes[this.state.currentIndex];
27        return <div className="App">
28            <header className="App-header">
29                <h3>Render Component with State and Props using TypeScript</h3>
30            </header>
31            <div style={{height: "5vh", padding: "1em", margin: "7em"}}>
32                <h4>{quoteToDisplay}</h4>
33            </div>
34            <button onClick={this.getNextQuote}>NEXT QUOTE</button>
35        </div>
36    }
37}
tsx

Call QuoteApp Component

Now <QuoteApp> component is ready to be called. All it needs is an array of quotes. Go to your src/index.tsx file and replace the code in that file with this code.

randomQuotes is an array of strings containing quotes. <QuoteApp> component is called with a prop quotes and its value randomQuotes.

Go to the browser and open http://localhost:3000. You should a quote rendered on the screen, it is the quote at index zero in the quotes array. Each time you click on the button, it displays a new quote.

1import React from 'react';
2import ReactDOM from 'react-dom';
3import './index.css';
4import QuoteApp from './QuoteApp';
5import * as serviceWorker from './serviceWorker';
6
7const randomQuotes: string[] = [
8    "Before you judge a man, walk a mile in his shoes. After that who cares?... He’s a mile away and you’ve got his shoes!",
9    "Better to remain silent and be thought a fool than to speak out and remove all doubt.",
10    "The best thing about the future is that it comes one day at a time.",
11    "The only mystery in life is why the kamikaze pilots wore helmets.",
12    "Light travels faster than sound. This is why some people appear bright until you hear them speak.",
13    "The difference between stupidity and genius is that genius has its limits"
14]
15ReactDOM.render(
16    <React.StrictMode>
17        <QuoteApp quotes={randomQuotes}/>
18    </React.StrictMode>,
19    document.getElementById('root')
20);
21serviceWorker.unregister();
tsx

Code on GitHub

You can access the entire code for this example on GitHub

Conclusion

You learned how to render a Class Component with state and props using TypeScript. In this code example, we used type alias to declare the prop and state types QuoteProps and QuoteState. This is because both QuoteProps and QuoteState are simple object type literals and strictly constrain the structure of these objects. But you can also make use of TypeScript interface for QuoteProps if there is need of implementing or extending that interface in the code.