Skip to Content
Lab 2

State & Events

Lab Overview

In this lab, you will create an interactive character counter application that demonstrates state management and event handling in React. The application will allow users to input text and see real-time statistics about their input, including character count, word count, and reading time. This lab focuses on state management, event handling, and component interaction using React hooks.


Workplace Context

Imagine you are a frontend developer working on a content management system. Your team needs a component that helps content writers track their progress while writing articles. The component should provide immediate feedback about the content length and estimated reading time, helping writers meet specific content requirements.

This lab will help you practice building interactive features that respond to user input in real-time, a common requirement in modern web applications.


Objectives

By the end of this lab, you will:

  1. Implement state management using the useState hook.
  2. Create and handle user events effectively.
  3. Build components that update their UI based on state changes.
  4. Implement the callback pattern for component communication.
  5. Create a responsive and user-friendly interface.

Instructions

Setup the Project

  1. Create a new React TypeScript project using Vite:
npm create vite@latest character-counter -- --template react-ts cd character-counter npm install
  1. Create the following folder structure:
src/ components/ TextInput/ TextInput.tsx StatsDisplay/ StatsDisplay.tsx CharacterCounter/ CharacterCounter.tsx types/ index.ts

Component Requirements

1. TextInput Component

Create a TextInput component that handles user input and communicates changes to its parent.

// types/index.ts export interface TextInputProps { onTextChange: (text: string) => void; placeholder?: string; initialValue?: string; }

2. StatsDisplay Component

Create a StatsDisplay component that shows various statistics about the text.

// types/index.ts export interface TextStats { characterCount: number; wordCount: number; readingTime: number; // in minutes } export interface StatsDisplayProps { stats: TextStats; showReadingTime?: boolean; }

3. CharacterCounter Component

Create a CharacterCounter component that combines the above components and manages the state.

// types/index.ts export interface CharacterCounterProps { minWords?: number; maxWords?: number; targetReadingTime?: number; // in minutes }

Activity Tasks

  1. Component Implementation:

    • Implement each component according to its interface requirements.
    • Use useState to manage text input and statistics.
    • Implement event handlers for text changes.
    • Calculate statistics in real-time.
  2. State Management:

    • Track the current text input.
    • Calculate and update statistics when text changes.
    • Handle edge cases (empty input, very long text).
  3. User Interface:

    • Create a responsive layout.
    • Show visual feedback for statistics.
    • Implement progress indicators for word count goals.
  4. Component Communication:

    • Use callbacks to pass data between components.
    • Ensure proper prop typing.
    • Handle optional props appropriately.

Completed Example

Here’s an example of the completed components:

Characters

0

Words

0

Min: 25 | Max: 100

Reading Time

0:00

Example Implementation

Here’s a starting point for the TextInput component using Tailwind CSS classes for styling:

// components/TextInput/TextInput.tsx import React from 'react'; import { TextInputProps } from '../../types'; export const TextInput: React.FC<TextInputProps> = ({ onTextChange, placeholder = 'Start typing...', initialValue = '' }) => { return ( <div className="w-full"> <textarea className="w-full p-4 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder={placeholder} defaultValue={initialValue} onChange={(e) => onTextChange(e.target.value)} rows={6} /> </div> ); };

Reflection Questions

  1. How did you handle state updates when the text changed?
  2. What considerations did you make when calculating reading time?
  3. How did you ensure the UI remained responsive during rapid text input?
  4. What challenges did you face when implementing the statistics calculations?

Submission

Submit your project via a GitHub repository using the Start Assignment link on Canvas. Your submission should include:

  1. All component implementations
  2. Example usage with documentation
  3. A README.md file explaining how to use the components

Grading Criteria

Your submission will be evaluated based on the following criteria:

CriteriaExcellentGoodFairNeeds Improvement
State Management Implementation
The component correctly implements and manages state using the useState hook.
15-13 pts
• State is properly initialized and typed
• State updates are handled correctly with useCallback
• State changes trigger appropriate UI updates
• Edge cases are handled gracefully
12-10 pts
• State is properly initialized
• State updates work correctly
• UI updates reflect state changes
9-7 pts
• Basic state management is implemented
• Some state updates work
• UI updates are inconsistent
6-0 pts
• State management is missing or incorrect
• State updates don’t work
• UI doesn’t reflect state changes
Event Handling
The component properly handles user events and updates accordingly.
15-13 pts
• Event handlers are properly implemented with TypeScript
• Events trigger appropriate state updates
• Edge cases are handled correctly
• Performance optimizations are implemented
12-10 pts
• Event handlers are implemented correctly
• Events update state properly
• Basic error handling is present
9-7 pts
• Basic event handling is implemented
• Some events work correctly
• Limited error handling
6-0 pts
• Event handlers are missing or incorrect
• Events don’t update state
• No error handling
Component Communication
Components communicate effectively using props and callbacks.
12-10 pts
• Props are properly typed with TypeScript interfaces
• Callbacks are implemented correctly with proper typing
• Data flows correctly between components
• Component composition is well-structured
9-7 pts
• Props are properly typed
• Callbacks work correctly
• Data flows between components
6-4 pts
• Basic prop types are defined
• Some callbacks work
• Limited component communication
3-0 pts
• Props are missing or incorrectly typed
• Callbacks don’t work
• Data flow is broken
User Interface & Experience
The interface is responsive and provides appropriate feedback.
8-7 pts
• UI is responsive and well-styled with Tailwind CSS
• Statistics update in real-time with smooth transitions
• Visual feedback is clear and helpful
• Accessibility features are implemented
6-5 pts
• UI is responsive and styled
• Statistics update in real-time
• Basic visual feedback is present
4-3 pts
• Basic UI is implemented
• Statistics update with some delay
• Limited visual feedback
2-0 pts
• UI is unresponsive or poorly styled
• Statistics don’t update
• No visual feedback

Total Points: 50