Interactive Data Table with Sorting in React (TypeScript)
This challenge asks you to build a reusable React component that displays data in a table format and allows users to sort the data by clicking on column headers. Creating such a component is a common task in web development, enabling users to easily analyze and understand tabular data. This exercise will test your understanding of React state management, event handling, and basic DOM manipulation.
Problem Description
You need to create a DataTable component that accepts an array of objects as data and an array of strings as columns. Each object in the data array represents a row in the table, and each string in the columns array represents a column header. The component should render the data in a table format, with each column header being clickable. Clicking a column header should sort the data based on that column in ascending order initially, and subsequent clicks should toggle between ascending and descending order.
Key Requirements:
- Data Display: The component must correctly display the data in a table format, with column headers and corresponding data rows.
- Sorting: Clicking a column header should sort the data based on the values in that column.
- Ascending/Descending Toggle: Subsequent clicks on the same column header should toggle the sorting order between ascending and descending.
- State Management: Use React state to manage the sorting state (which column is being sorted and the sorting order).
- Reusability: The component should be reusable with different data and column configurations.
- TypeScript: The code must be written in TypeScript.
Expected Behavior:
- The table should initially display the data in its original order.
- Clicking a column header should sort the data based on that column.
- Clicking the same column header again should reverse the sorting order.
- The currently sorted column should be visually indicated (e.g., with a different background color or an arrow icon).
- The table should render correctly even if the data is empty.
Edge Cases to Consider:
- Empty Data: Handle the case where the
dataarray is empty. Display a message indicating that there is no data to display. - Missing Data: Handle cases where some objects in the
dataarray might be missing values for certain columns. Consider displaying a default value (e.g., "N/A") or skipping the row. - Data Types: The data in each column might have different data types (e.g., strings, numbers, dates). Ensure that the sorting logic handles these different types correctly. Numbers should be sorted numerically, and strings should be sorted lexicographically.
- Case-Insensitive Sorting: Consider whether the sorting should be case-insensitive for string columns.
Examples
Example 1:
Input:
data: [{name: "Alice", age: 30, city: "New York"}, {name: "Bob", age: 25, city: "Los Angeles"}, {name: "Charlie", age: 35, city: "Chicago"}]
columns: ["name", "age", "city"]
Output:
A table with headers "name", "age", "city". Initially, the data is displayed in the order provided. Clicking "age" sorts by age ascending. Clicking "age" again sorts by age descending.
Explanation: The component renders the table and updates the data order based on the clicked column and sorting direction.
Example 2:
Input:
data: []
columns: ["name", "age", "city"]
Output:
A message indicating "No data to display."
Explanation: The component handles the empty data case gracefully.
Example 3:
Input:
data: [{name: "Alice", age: 30}, {name: "Bob", age: 25, city: "Los Angeles"}]
columns: ["name", "age", "city"]
Output:
A table with headers "name", "age", "city". The row with missing "city" data will display "N/A" in the city column.
Explanation: The component handles missing data by displaying a default value.
Constraints
- The component should be implemented as a functional component using React Hooks.
- The sorting algorithm should have a time complexity of O(n log n) or better, where n is the number of rows in the data. Simple bubble sort is discouraged.
- The component should be responsive and render correctly on different screen sizes.
- The component should be well-documented with clear and concise comments.
- The component should be written in TypeScript with proper type annotations.
Notes
- Consider using the
useStatehook to manage the sorting state. - You can use the
sortmethod of the JavaScript array to sort the data. - Think about how to visually indicate the currently sorted column.
- Focus on creating a clean, reusable, and well-documented component.
- You can use any CSS styling you prefer, but keep it simple and functional. No need for complex styling.
- Error handling is not explicitly required, but consider how your component would behave with invalid input data.