Home Quizzes Leaderboard Competitions Learn Hire Us
About Contact
Log In Sign Up
Learn Next.js Components, Props & TypeScript

Components, Props & TypeScript

⏱ 15 min read read
Defining Components with TypeScript:

// Define prop types with an interface or type

interface ButtonProps {

label: string;

onClick: () => void;

variant?: 'primary' | 'danger' | 'ghost'; // optional

disabled?: boolean;

}

export default function Button({ label, onClick, variant =
'primary', disabled = false }: ButtonProps) {

return (

<button onClick={onClick} disabled={disabled}>

{label}

</button>

);

}

children Prop:

// React.ReactNode = anything React can render

interface CardProps {

title: string;

children: React.ReactNode;

}

export function Card({ title, children }: CardProps) {

return (

<div className="card">

<h2>{title}</h2>

<div>{children}</div>

</div>

);

}

// Usage:

<Card title="Grades">

<p>Alice: 92</p>

<p>Bob: 78</p>

</Card>

Common TypeScript Types for React:

React.ReactNode --- anything renderable (JSX, string, null, array)

React.FC<Props> --- function component (less common now)

React.CSSProperties --- inline style object

React.MouseEvent --- click event

React.ChangeEvent<HTMLInputElement> --- input change event

React.FormEvent<HTMLFormElement> --- form submit event

Component Composition --- Slot Pattern:

interface ModalProps {

header: React.ReactNode;

body: React.ReactNode;

footer?: React.ReactNode;

}

function Modal({ header, body, footer }: ModalProps) {

return (

<div className="modal">

<div className="modal-header">{header}</div>

<div className="modal-body">{body}</div>

{footer && <div className="modal-footer">{footer}</div>}

</div>

);

}
Code Example
// components/StudentList.tsx

interface Student {

id: number;

name: string;

grade: number;

subject: string;

}

interface StudentRowProps {

student: Student;

onDelete: (id: number) => void;

}

function StudentRow({ student, onDelete }: StudentRowProps) {

const { id, name, grade, subject } = student;

const pass = grade >= 70;

return (

<tr>

<td>{name}</td>

<td>{subject}</td>

<td style={{ color: pass ? 'green' : 'red' }}>{grade}</td>

<td><span>{pass ? 'Pass' : 'Fail'}</span></td>

<td>

<button onClick={() => onDelete(id)}>Remove</button>

</td>

</tr>

);

}

interface StudentListProps {

students: Student[];

onDelete: (id: number) => void;

emptyMessage?: string;

}

export default function StudentList({

students,

onDelete,

emptyMessage = 'No students yet.',

}: StudentListProps) {

if (students.length === 0) return <p>{emptyMessage}</p>;

return (

<table>

<thead>

<tr>

<th>Name</th><th>Subject</th><th>Grade</th>

<th>Status</th><th>Action</th>

</tr>

</thead>

<tbody>

{students.map(s => (

<StudentRow key={s.id} student={s} onDelete={onDelete} />

))}

</tbody>

</table>

);

}
← Styling --- CSS Modules, Tailwind & Glob State & Client Interactivity →

Log in to track your progress and earn badges as you complete lessons.

Log In to Track Progress