Building a Simple Task Manager with Flux Architecture in React
This challenge asks you to implement a basic task manager application using the Flux architecture in React with TypeScript. Flux provides a unidirectional data flow, making application state management more predictable and easier to debug, especially in larger applications. Successfully completing this challenge demonstrates understanding of Flux principles and their practical application in a React environment.
Problem Description
You are tasked with building a simple task manager application. The application should allow users to:
- Add Tasks: Users should be able to input a task description and add it to the list.
- View Tasks: The application should display a list of all tasks.
- Mark Tasks as Complete: Users should be able to toggle the "completed" status of a task.
- Delete Tasks: Users should be able to remove tasks from the list.
The application must adhere to the Flux architecture, consisting of:
- Action Creators: Functions that create action objects to describe events.
- Dispatcher: A central hub that receives actions and dispatches them to stores.
- Stores: Manage the application state and respond to actions by updating the state.
- React View (Component): Displays the data from the store and allows users to interact with the application, triggering actions.
Key Requirements:
- Unidirectional Data Flow: Actions are dispatched, stores update state, and views re-render based on the updated state.
- Immutability: State updates in the store should be immutable (create new state objects instead of modifying existing ones).
- TypeScript: The entire solution must be written in TypeScript, with appropriate type annotations.
- Clear Separation of Concerns: The code should be well-organized and modular, with clear separation between action creators, dispatcher, stores, and components.
Expected Behavior:
- When a new task is added, an action is dispatched, the store updates the task list, and the view re-renders to display the new task.
- When a task is marked as complete, an action is dispatched, the store updates the task's status, and the view re-renders to reflect the change.
- When a task is deleted, an action is dispatched, the store removes the task, and the view re-renders to display the updated list.
- The application should remain responsive and handle updates efficiently.
Edge Cases to Consider:
- Empty task list: The view should gracefully handle the case where there are no tasks.
- Invalid input: Consider how to handle empty task descriptions when adding a new task (e.g., display an error message).
- Large task list: While not a primary focus, consider the potential performance implications of a very large task list.
Examples
Example 1:
Input: Initial state: []
Action: Add Task with description "Buy groceries"
Output: State: [{id: 1, description: "Buy groceries", completed: false}]
Explanation: The action creator creates an action, the dispatcher sends it to the store, the store adds a new task object to the state array with a unique ID and default 'completed' status, and the React component re-renders to display the new task.
Example 2:
Input: State: [{id: 1, description: "Buy groceries", completed: false}, {id: 2, description: "Walk the dog", completed: true}]
Action: Toggle Complete for task with id 1
Output: State: [{id: 1, description: "Buy groceries", completed: true}, {id: 2, description: "Walk the dog", completed: true}]
Explanation: The action creator creates an action, the dispatcher sends it to the store, the store finds the task with id 1 and toggles its 'completed' property, and the React component re-renders to display the updated task list.
Example 3:
Input: State: [{id: 1, description: "Buy groceries", completed: false}, {id: 2, description: "Walk the dog", completed: true}]
Action: Delete Task with id 2
Output: State: [{id: 1, description: "Buy groceries", completed: false}]
Explanation: The action creator creates an action, the dispatcher sends it to the store, the store removes the task with id 2 from the state array, and the React component re-renders to display the updated task list.
Constraints
- Time Limit: You have approximately 2-3 hours to complete this challenge.
- Dependencies: You are allowed to use React, React DOM, and TypeScript. No other external libraries are permitted for state management.
- Code Size: Keep the code reasonably concise and focused on demonstrating the Flux architecture. Avoid unnecessary complexity.
- Task ID Generation: Use a simple incrementing ID generator for task IDs. Uniqueness is important.
- Immutability: State updates must be immutable. Avoid directly modifying the existing state array.
Notes
- Start by defining the data structure for a task (e.g., an interface or type).
- Consider using a simple object to implement the dispatcher.
- Focus on the core principles of Flux: unidirectional data flow, actions, stores, and views.
- Don't worry about styling or advanced features. The primary goal is to demonstrate the Flux architecture.
- Test your code thoroughly to ensure that actions are correctly dispatched, stores are updated as expected, and the view re-renders appropriately.
- Think about how you would extend this application to handle more complex features in the future.