Katkat

Debug React Sorting, Persistence, Routing, and Accessibility

HackerRankSoftware Engineer · Online Assessment

Last updated

This problem tests your ability to identify and rectify common React anti-patterns, including state mutations, improper side-effect handling, and accessibility failures in a data-driven application.

Problem Statement

You are provided with a legacy React component that manages a list of "Tasks." The current implementation has the following critical bugs:

  1. Sorting Mutation: Clicking the sort button mutates the original tasks array directly in the state, causing unpredictable UI behavior.
  2. Persistence Loss: Refreshing the page resets the list, and changes are not synced with localStorage.
  3. Accessibility (a11y): The filter inputs and task checkboxes lack proper labeling, violating screen-reader compatibility standards.
  4. Routing: The task detail view is implemented with a manual conditional render that does not update the URL, making the page non-bookmarkable.

Task

Refactor the following snippet to ensure immutability, persist data to localStorage, implement standard ARIA roles, and integrate react-router-dom for navigation.

// Current buggy snippet
function TaskManager() {
  const [tasks, setTasks] = useState(initialTasks);

  const handleSort = () => {
    // BUG: Mutating state directly
    tasks.sort((a, b) => a.title.localeCompare(b.title));
    setTasks(tasks);
  };

  return (
    
      
      {tasks.map(t => {t.title})}
      Sort
    
  );
}

Requirements

  • Implement deep cloning for sorting.
  • Use useEffect to sync the state with localStorage on update.
  • Use aria-label for inputs and ensure buttons are semantically correct.
  • Replace conditional rendering with react-router-dom routes for /tasks and /tasks/:id.

Constraints

  • Assume initialTasks is an array of objects { id: number, title: string, completed: boolean }.

Hints

Hint 1

To solve the mutation bug, always use the spread operator `[...tasks]` to create a new array before calling `.sort()`.

Hint 2

Use a `useEffect` hook with `[tasks]` as the dependency array to trigger `localStorage.setItem` whenever the task list changes.

Hint 3

Ensure interactive elements have explicit labels; for the search input, use `aria-label="Search tasks"` to satisfy WCAG requirements.

Follow-up questions

  • How would you optimize performance if the `tasks` list grows to contain thousands of items?
  • Explain how you would implement error boundaries to handle crashes when retrieving malformed data from `localStorage`.
  • What are the trade-offs between using a global state manager (like Redux or Context API) versus prop drilling for this specific task list?