Skip to content

Instantly share code, notes, and snippets.

@stevebrownlee
Last active October 21, 2025 23:52
Show Gist options
  • Save stevebrownlee/3b52dfc1098ebc6ad978dd36b21ef665 to your computer and use it in GitHub Desktop.
Save stevebrownlee/3b52dfc1098ebc6ad978dd36b21ef665 to your computer and use it in GitHub Desktop.
React component design using TypeScript
import React, { useState } from 'react';
// Types/Interfaces
interface Task {
id: string;
title: string;
completed: boolean;
}
interface TaskItemProps {
task: Task;
onToggle: (id: string) => void;
}
interface TaskListProps {
tasks: Task[];
onToggle: (id: string) => void;
}
interface AddTaskFormProps {
onAddTask: (title: string) => void;
}
// TaskItem Component
function TaskItem({ task, onToggle }: TaskItemProps) {
return (
<div style={{ display: 'flex', alignItems: 'center', padding: '8px', borderBottom: '1px solid #eee' }}>
<input
type="checkbox"
checked={task.completed}
onChange={() => onToggle(task.id)}
style={{ marginRight: '12px' }}
/>
<span style={{ textDecoration: task.completed ? 'line-through' : 'none', color: task.completed ? '#888' : '#000' }}>
{task.title}
</span>
</div>
);
}
// TaskList Component
function TaskList({ tasks, onToggle }: TaskListProps) {
if (tasks.length === 0) {
return <p style={{ color: '#888', padding: '16px' }}>No tasks yet. Add one below!</p>;
}
return (
<div style={{ border: '1px solid #ddd', borderRadius: '4px', marginBottom: '16px' }}>
{tasks.map((task) => (
<TaskItem key={task.id} task={task} onToggle={onToggle} />
))}
</div>
);
}
// AddTaskForm Component
function AddTaskForm({ onAddTask }: AddTaskFormProps) {
const [title, setTitle] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (title.trim()) {
onAddTask(title.trim());
setTitle('');
}
};
return (
<form onSubmit={handleSubmit} style={{ display: 'flex', gap: '8px' }}>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Enter task title..."
style={{ flex: 1, padding: '8px', border: '1px solid #ddd', borderRadius: '4px' }}
/>
<button type="submit" style={{ padding: '8px 16px', backgroundColor: '#007bff', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer' }}>
Add Task
</button>
</form>
);
}
// Main App Component (demonstrates usage)
function App() {
const [tasks, setTasks] = useState<Task[]>([
{ id: '1', title: 'Complete mock interview', completed: false },
{ id: '2', title: 'Review React concepts', completed: true },
]);
const handleToggle = (id: string) => {
setTasks(tasks.map(task =>
task.id === id ? { ...task, completed: !task.completed } : task
));
};
const handleAddTask = (title: string) => {
const newTask: Task = {
id: Date.now().toString(),
title,
completed: false,
};
setTasks([...tasks, newTask]);
};
return (
<div style={{ maxWidth: '600px', margin: '40px auto', padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<h1>Task Manager</h1>
<TaskList tasks={tasks} onToggle={handleToggle} />
<AddTaskForm onAddTask={handleAddTask} />
</div>
);
}
export default App;

Mock Interview Scenario: React Component Design

Context

You're building a simple task management feature for a productivity app. Users should be able to view tasks, mark them as complete, and add new tasks.

Your Task

Design and plan the implementation for three React components using TypeScript:

  1. TaskList - Displays a list of tasks
  2. TaskItem - Represents a single task with a checkbox and text
  3. AddTaskForm - A form to add new tasks

Requirements

  • Tasks should have: id, title, and completed status
  • Users can toggle a task's completion status by clicking a checkbox
  • Users can add new tasks through a simple form with a text input and submit button
  • The task list should update when tasks are added or their status changes

What We're Looking For

  • How you think about component structure and data flow
  • Your approach to TypeScript types/interfaces
  • How you handle state management
  • Component composition and props design

Time

Take 20-30 minutes to:

  1. Explain your component architecture and data flow
  2. Define the TypeScript interfaces/types you'll need
  3. Write out the component signatures (props and basic structure)
  4. Walk through how the components interact

You don't need to implement every detail, but show your thinking process.

You can use https://codesandbox.io/p/sandbox/react-ts to implement your code

Here is some starter code

function App() {
  const [tasks, setTasks] = useState<Task[]>([
    { id: "1", title: "Complete mock interview", completed: false },
    { id: "2", title: "Review React concepts", completed: true },
  ]);

  return (
    <div
      style={{
        maxWidth: "600px",
        margin: "40px auto",
        padding: "20px",
        fontFamily: "Arial, sans-serif",
      }}
    >
      <h1>Task Manager</h1>
    </div>
  );
}

export default App;

Follow-up Questions (After Initial Design)

Scalability & Performance

  1. If this task list grew to 1,000+ tasks, what performance concerns would you have? How would you address them?

    • Look for: virtualization, pagination, memoization
  2. How would you prevent unnecessary re-renders in the TaskItem components?

    • Look for: React.memo, useCallback, useMemo

State Management

  1. Right now, where would you keep the task state? What if multiple components across different parts of the app needed access to tasks?
    • Look for: context API, state management libraries, lifting state

Features & Edge Cases

  1. How would you add the ability to edit a task's title? Walk me through the changes you'd make.

    • Look for: controlled components, handling edit mode state
  2. What happens if someone tries to add an empty task? How would you handle validation?

    • Look for: form validation, error states, user feedback

Real-World Scenarios

  1. If tasks needed to be saved to a backend API, how would your design change?

    • Look for: async operations, loading states, error handling, optimistic updates
  2. How would you test these components?

    • Look for: unit testing approach, testing user interactions, mocking

TypeScript Specifics

  1. Would you use types or interfaces for your task data? Why?

    • Look for: understanding of differences, consistency reasoning
  2. How would you handle optional properties if tasks could have additional fields like priority or dueDate?

    • Look for: optional properties, union types, type guards
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment