25. React and TypeScript#
25.1. What is React#
React is a popular JavaScript library for building user interfaces, particularly single-page applications. It allows developers to create reusable UI components and manage the state of their applications efficiently.

25.2. What is TypeScript?#
TypeScript is a superset of JavaScript that adds static types. This allows developers to catch errors at compile time rather than at runtime, making the development process smoother and more reliable.
25.3. Setting Up Your Development Environment#
25.3.1. Install Node.js#
Node.js is a JavaScript runtime that allows you to run JavaScript code outside of a browser. It also comes with npm (Node Package Manager), which you’ll use to install libraries and tools.
Download
Node.js: Go to the Node.js official website and download the LTS version suitable for your operating system.Install
Node.js: Follow the installation instructions provided for your operating system. After installation, you can verify the installation by running the following commands in your terminal:node -v npm -v
25.3.2. Create a New React Project with TypeScript Using Vite#
Vite is a modern frontend build tool that provides a faster and leaner development experience. We’ll use Vite to create our React project with TypeScript.
Open your terminal: Make sure you are in the directory where you want to create your new project.
Run the create command: Use
npmto create a new project withVite.npm create vite@4.1.0
This command will prompt you to provide the project name and select the framework and variant.
Project name: Enter the desired name for your project (e.g., my-react-app).
Select a framework: Choose
React.Select a variant: Choose
TypeScript
Navigate to your project directory:
cd my-react-appInstall dependencies:
npm installRun the development server:
npm run devThis will start the development server, and you should see output similar to this:
VITE v4.1.0 ready in 300 ms ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose
25.4. Understanding the Project Structure#
Once your project is created, you will notice several files and folders. Here are the key components:
src/: This directory contains your source code.App.tsx: The main application component.main.tsx: The entry point of your React application.
index.html: The HTML template for your app.tsconfig.json: Configuration file for TypeScript.vite.config.ts: Configuration file for Vite.
25.5. Creating Your First Component#
Let’s create a simple React component to get familiar with the basic concepts.
25.5.1. Create a new file in the src directory named Hello.tsx#
// src/Hello.tsx
import React from "react";
interface HelloProps {
name: string;
}
const Hello: React.FC<HelloProps> = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
export default Hello;
In
TypeScript, aninterfaceis a way to define the structure of an object. It specifies the types of properties that an object can have.In our example, we define an
interfaceHelloProps, Thisinterfacespecifies that any object of typeHelloPropsmust have anameproperty of typestring.
React componentscan be written as eitherclasscomponents orfunctionalcomponents. Functional components are simpler and often preferred for their conciseness and ease of use.In our example, We declare a
constantnamedHello. it means thatHellowill always refer to the same component function.This is a common practice in modern JavaScript to ensure that variables and constants are not accidentally reassigned, leading to more predictable and maintainable code.
React.FC<HelloProps>: We specify thatHellois a functional component (React.FC) that takes props of typeHelloProps.This ensures that TypeScript will enforce the
HelloPropstype for the props passed toHello.
25.5.2. Modify App.tsx to include your new component:#
// src/App.tsx
import React from "react";
import Hello from "./Hello";
const App: React.FC = () => {
return (
<div>
<Hello name="World" />
</div>
);
};
export default App;
25.6. Creating a ListGroup Component#
25.6.1. Setting Up Bootstrap#
Install Bootstrap and its peer dependencies:
npm install bootstrap@5.2.3Import Bootstrap CSS
Open
src/main.tsxand add the following line to import theBootstrapCSS:
import "bootstrap/dist/css/bootstrap.min.css"; import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./index.css"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( <React.StrictMode> <App /> </React.StrictMode> );
25.6.2. Creating the ListGroup Component#
Create a new file
src/components/ListGroup.tsxand define the ListGroup component:classis a reserved keyword in javascript / typescript. We need to substitute it asclassName. (Hint:ctrl + Ddo multiple-cursor modification)
Add the following into the
ListGroup.tsxConditional Rendering
The
getMessagefunction checks if there are any items in the list. If the list is empty (items.length === 0), it returns a paragraph element with the message"No item found".Ternary Operator
(&&): If the length of items is 0, the<p>No item found.</p>message is rendered.
import React from "react"; function ListGroup() { let items = ["New York", "San Francisco", "Tokyo", "London", "Paris"]; items = []; const getMessage = () => { return items.length === 0 && <p>No item found.</p>; }; return ( <React.Fragment> <h1>List</h1> {getMessage()} <ul className="list-group"> <li>test</li> {items.map((item) => ( <li key={item} className="list-group-item"> {item} </li> ))} </ul> </React.Fragment> ); } export default ListGroup;
25.6.3. Handle click events#
Using State with
Hooks
React Hooksallow you to use state and other React features without writing a class.The
useState hookis particularly useful for managingstateinfunctional components.We use the
useState hookto manage the selected index of our list items. By callingsetSelectedIndex, we update theselectedIndex, which triggers are-renderof the component with the new state.
Handling Click Events
Handling
clickevents in React involves attaching anonClickevent handler to aDOMelement.When a list item is clicked, the arrow function sets the
selectedIndexto theindexof the clicked item.
Dynamic Class Names
We use a conditional expression to apply different class names based on whether a list item is selected.
If the current item’s
indexmatchesselectedIndex, we apply theactiveclass to highlight the item.
import React, { MouseEvent, useState } from "react";
function ListGroup() {
let items = ["New York", "San Francisco", "Tokyo", "London", "Paris"];
// Hook
const [selectedIndex, setSelectedIndex] = useState(0);
const getMessage = () => {
return items.length === 0 && <p>No item found.</p>;
};
return (
<React.Fragment>
<h1>List</h1>
{getMessage()}
<ul className="list-group">
{items.map((item, index) => (
<li
key={index}
className={
selectedIndex === index
? "list-group-item active"
: "list-group-item"
}
// onClick={() => console.log(item + "been clicked\n" + index)}
onClick={() => {
setSelectedIndex(index);
}}
>
{item}
</li>
))}
</ul>
</React.Fragment>
);
}
export default ListGroup;
25.6.4. Passing data via props#
In this section, we will extend our ListGroup component to accept data through props.
This approach allows us to make our component more reusable and flexible by allowing it to receive different sets of data and headings.
Props Interface
In
TypeScript, we define aninterfaceto specify the types ofpropsthat a component will receive.This ensures that our
componentis used correctly, with the correct types of data being passed in.
interface ListGroupProps { items: string[]; heading: string; }
Destructuring Props
When we define the
component, we candestructurethepropsdirectly in the function parameter list. This makes the code cleaner and easier to read.Instead of accessing
props.itemsandprops.headingwithin the component, we destructure these properties directly in the function signature.
function ListGroup({ items, heading }: ListGroupProps) { // Component logic here }
Using the Component
To see the
ListGroup componentin action, we can create aparent componentthat passes different sets of data to it.
// src/App.tsx import React from "react"; import Hello from "./Hello"; import ListGroup from "./components/ListGroup"; const App: React.FC = () => { let city_items = ["New York", "San Francisco", "Tokyo", "London", "Paris"]; let cat_items = [ "Maine Coon", "Ragdoll", "Persian", "Abyssinian", "Siamese", ]; return ( <div> <Hello name="World" /> <ListGroup items={city_items} heading="Cities"></ListGroup> <ListGroup items={cat_items} heading="Cats"></ListGroup> </div> ); }; export default App;
25.6.5. Passing functions via Props#
In this section, we’ll focus on how to pass functions as props to a component.
This allows a parent component to control how certain actions are handled when they occur in a child component.
Function as Prop
In
React,functionscan be passed aspropstochild components. This allows theparent componentto define the behavior for certain actions in the child component.onSelectItem: Afunction propthat takes two arguments,headinganditem. This function will be called when a list item is clicked.
interface ListGroupProps { items: string[]; heading: string; onSelectItem: (heading: string, item: string) => void; }
Callback Functions
A
callback functionis afunctionpassed intoanother functionas an argument. This technique is useful for handling events that occur in child components within the parent component.handleSelectItem: Thisfunctionis defined in theparent component (App). It logs the heading and item to theconsolewhenever it is called.
const handleSelectItem = (heading: string, item: string) => { console.log(`Heading: ${heading}, Item: ${item}`); };
Using the Component
To see the
ListGroupcomponent in action, we can create aparent component (App)that passes thehandleSelectItemfunction to it.
import React from "react"; import ListGroup from "./components/ListGroup"; const App: React.FC = () => { const city_items = [ "New York", "San Francisco", "Tokyo", "London", "Paris", ]; const cat_items = [ "Maine Coon", "Ragdoll", "Persian", "Abyssinian", "Siamese", ]; const handleSelectItem = (heading: string, item: string) => { console.log(`Heading: ${heading}, Item: ${item}`); }; return ( <div> <ListGroup items={city_items} heading="Cities" onSelectItem={handleSelectItem} /> <ListGroup items={cat_items} heading="Cats" onSelectItem={handleSelectItem} /> </div> ); }; export default App;
25.7. State vs Props#

25.8. Creating a component accept children#
In this section, we’ll focus on how to create a React component that can accept and render children elements.
Children PropIn
React, thechildren propis a special prop that is automatically passed to every component. It contains the content nested inside the component’s opening and closing tags when it is used.children: Thispropis of typeReactNode, which can represent any renderable React content, includingelements,strings,numbers,fragments, andarrays.
interface AlertProps { children: ReactNode; }
Using the Component
<Alert> Hello <span>World</span> </Alert>