ReactJs
Coding Challenges

To explore the coding challenges available on InterviewPro React (opens in a new tab), follow this detailed breakdown of each challenge. Each section includes the problem overview, a summary of the core functionality, and example implementations to illustrate key concepts.


1. Todo List

Overview: The Todo List challenge focuses on creating a task management application where users can add, edit, delete, and filter tasks. This challenge helps practice managing component state and handling user interactions.

Core Functionality:

  • Add Tasks: Input a task and add it to the list.
  • Edit Tasks: Modify existing tasks.
  • Delete Tasks: Remove tasks from the list.
  • Filter Tasks: Show tasks based on their completion status (e.g., all, completed, active).

Example Implementation:

import React, { useState } from 'react';
 
const TodoList = () => {
  const [tasks, setTasks] = useState([]);
  const [input, setInput] = useState('');
  const [filter, setFilter] = useState('all');
 
  const addTask = () => {
    setTasks([...tasks, { text: input, completed: false }]);
    setInput('');
  };
 
  const toggleCompletion = (index) => {
    const updatedTasks = tasks.map((task, i) =>
      i === index ? { ...task, completed: !task.completed } : task
    );
    setTasks(updatedTasks);
  };
 
  const filteredTasks = tasks.filter(task => 
    filter === 'all' ? true :
    filter === 'completed' ? task.completed :
    !task.completed
  );
 
  return (
    <div>
      <input value={input} onChange={(e) => setInput(e.target.value)} />
      <button onClick={addTask}>Add Task</button>
      <div>
        <button onClick={() => setFilter('all')}>All</button>
        <button onClick={() => setFilter('completed')}>Completed</button>
        <button onClick={() => setFilter('active')}>Active</button>
      </div>
      <ul>
        {filteredTasks.map((task, index) => (
          <li key={index}>
            <span 
              onClick={() => toggleCompletion(index)} 
              style={{ textDecoration: task.completed ? 'line-through' : 'none' }}
            >
              {task.text}
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
};
 
export default TodoList;

2. Countdown Application

Overview: The Countdown Application challenge involves creating a timer that allows users to set a countdown duration, start, pause, and reset the timer. It helps practice handling time-based interactions and state management.

Core Functionality:

  • Set Duration: Input the countdown time.
  • Start Timer: Begin the countdown.
  • Pause Timer: Pause the countdown.
  • Reset Timer: Reset to the initial time.

Example Implementation:

import React, { useState, useEffect } from 'react';
 
const CountdownTimer = () => {
  const [time, setTime] = useState(0);
  const [initialTime, setInitialTime] = useState(0);
  const [isActive, setIsActive] = useState(false);
 
  useEffect(() => {
    let interval = null;
    if (isActive && time > 0) {
      interval = setInterval(() => {
        setTime(prevTime => prevTime - 1);
      }, 1000);
    } else if (!isActive && time !== 0) {
      clearInterval(interval);
    }
    return () => clearInterval(interval);
  }, [isActive, time]);
 
  const startTimer = () => {
    setIsActive(true);
  };
 
  const pauseTimer = () => {
    setIsActive(false);
  };
 
  const resetTimer = () => {
    setIsActive(false);
    setTime(initialTime);
  };
 
  return (
    <div>
      <input
        type="number"
        value={initialTime}
        onChange={(e) => setInitialTime(Number(e.target.value))}
        placeholder="Enter time in seconds"
      />
      <button onClick={() => setTime(initialTime)}>Set Timer</button>
      <button onClick={startTimer}>Start</button>
      <button onClick={pauseTimer}>Pause</button>
      <button onClick={resetTimer}>Reset</button>
      <div>Time Remaining: {time} seconds</div>
    </div>
  );
};
 
export default CountdownTimer;

3. Autocomplete Search

Overview: The Autocomplete Search challenge requires building a search component that provides suggestions based on user input. It focuses on dynamic data filtering and display.

Core Functionality:

  • Search Input: Filter suggestions based on user input.
  • Display Suggestions: Show matching results as the user types.

Example Implementation:

import React, { useState } from 'react';
 
const Autocomplete = () => {
  const [input, setInput] = useState('');
  const [suggestions, setSuggestions] = useState([]);
  const data = ['Apple', 'Banana', 'Cherry', 'Date', 'Fig', 'Grape', 'Kiwi'];
 
  const handleChange = (e) => {
    const value = e.target.value;
    setInput(value);
    if (value.length > 0) {
      setSuggestions(data.filter(item =>
        item.toLowerCase().includes(value.toLowerCase())
      ));
    } else {
      setSuggestions([]);
    }
  };
 
  return (
    <div>
      <input
        type="text"
        value={input}
        onChange={handleChange}
        placeholder="Search..."
      />
      <ul>
        {suggestions.map((suggestion, index) => (
          <li key={index}>{suggestion}</li>
        ))}
      </ul>
    </div>
  );
};
 
export default Autocomplete;

4. Nested Comments

Overview: The Nested Comments challenge involves creating a comment section with support for replies, edits, and deletions. This challenge focuses on managing nested data structures and user interactions.

Core Functionality:

  • Add Comments: Post new comments.
  • Reply to Comments: Add replies to existing comments.
  • Edit Comments: Modify existing comments.
  • Delete Comments: Remove comments from the list.

Example Implementation:

import React, { useState } from 'react';
 
const NestedComments = () => {
  const [comments, setComments] = useState([]);
  const [input, setInput] = useState('');
  const [reply, setReply] = useState('');
  const [editing, setEditing] = useState(null);
 
  const addComment = () => {
    setComments([...comments, { text: input, replies: [] }]);
    setInput('');
  };
 
  const addReply = (index) => {
    const newComments = comments.map((comment, i) =>
      i === index
        ? { ...comment, replies: [...comment.replies, reply] }
        : comment
    );
    setComments(newComments);
    setReply('');
  };
 
  const editComment = (index, newText) => {
    const newComments = comments.map((comment, i) =>
      i === index ? { ...comment, text: newText } : comment
    );
    setComments(newComments);
    setEditing(null);
  };
 
  const deleteComment = (index) => {
    const newComments = comments.filter((_, i) => i !== index);
    setComments(newComments);
  };
 
  return (
    <div>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="Add a comment"
      />
      <button onClick={addComment}>Post Comment</button>
      <div>
        {comments.map((comment, index) => (
          <div key={index}>
            <span>{comment.text}</span>
            <button onClick={() => setEditing(index)}>Edit</button>
            <button onClick={() => deleteComment(index)}>Delete</button>
            {editing === index && (
              <input
                type="text"
                defaultValue={comment.text}
                onBlur={(e) => editComment(index, e.target.value)}
              />
            )}
            <input
              value={reply}
              onChange={(e) => setReply(e.target.value)}
              placeholder="Reply..."
            />
            <button onClick={() => addReply(index)}>Add Reply</button>
            <div>
              {comment.replies.map((r, i) => (
                <div key={i}>{r}</div>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};
 
export default NestedComments;

5. File Explorer

Overview: The File Explorer challenge involves building a file explorer with nested folders and expand/collapse functionality. This helps practice managing hierarchical data and UI interactions.

Core Functionality:

  • Display Folders and Files: Show a hierarchical view.
  • Expand/Collapse: Toggle visibility of nested items.

Example Implementation:

import React, { useState } from 'react';
 
const FileExplorer = () => {
  const [expanded, setExpanded] = useState({});
 
  const toggleExpand = (folder) => {
    setExpanded(prev => ({
      ...prev,
      [folder]: !prev[folder]
    }));
  };
 
  const data = {
    'Folder1': ['File1', 'File2'],
    'Folder
 
2': {
      'Subfolder1': ['File3'],
      'Subfolder2': ['File4']
    }
  };
 
  const renderItems = (items, depth = 0) => (
    <ul>
      {Object.entries(items).map(([key, value]) => (
        <li key={key}>
          {typeof value === 'object' ? (
            <>
              <span onClick={() => toggleExpand(key)}>
                {expanded[key] ? '[-]' : '[+]'} {key}
              </span>
              {expanded[key] && renderItems(value, depth + 1)}
            </>
          ) : (
            <span>{value}</span>
          )}
        </li>
      ))}
    </ul>
  );
 
  return (
    <div>
      {renderItems(data)}
    </div>
  );
};
 
export default FileExplorer;

6. Shopping Cart

Overview: The Shopping Cart challenge focuses on building a shopping cart system with product management, cart functionalities, and checkout simulation. This challenge emphasizes managing state and handling user actions.

Core Functionality:

  • Add Products: Manage product listings and add items to the cart.
  • View Cart: Display cart items and total amount.
  • Checkout: Simulate the checkout process.

Example Implementation:

import React, { useState } from 'react';
 
const ShoppingCart = () => {
  const [cart, setCart] = useState([]);
  const [products] = useState([
    { id: 1, name: 'Product1', price: 10 },
    { id: 2, name: 'Product2', price: 20 },
  ]);
 
  const addToCart = (product) => {
    setCart([...cart, product]);
  };
 
  const totalAmount = cart.reduce((acc, item) => acc + item.price, 0);
 
  return (
    <div>
      <h1>Products</h1>
      {products.map(product => (
        <div key={product.id}>
          <span>{product.name} - ${product.price}</span>
          <button onClick={() => addToCart(product)}>Add to Cart</button>
        </div>
      ))}
      <h2>Cart</h2>
      <ul>
        {cart.map((item, index) => (
          <li key={index}>{item.name} - ${item.price}</li>
        ))}
      </ul>
      <div>Total: ${totalAmount}</div>
      <button onClick={() => alert('Checkout not implemented')}>Checkout</button>
    </div>
  );
};
 
export default ShoppingCart;

7. Pagination

Overview: The Pagination challenge involves creating a component that handles navigating through large datasets by displaying a subset of data at a time. This helps practice managing state and rendering data efficiently.

Core Functionality:

  • Page Numbers: Display pagination controls.
  • Navigation Buttons: Allow users to navigate through pages.

Example Implementation:

import React, { useState } from 'react';
 
const Pagination = () => {
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 10;
  const totalItems = 100; // Example total number of items
  const totalPages = Math.ceil(totalItems / itemsPerPage);
 
  const handlePageChange = (page) => {
    setCurrentPage(page);
  };
 
  const pages = Array.from({ length: totalPages }, (_, i) => i + 1);
 
  return (
    <div>
      <ul>
        {pages.map(page => (
          <li key={page}>
            <button onClick={() => handlePageChange(page)}>
              {page}
            </button>
          </li>
        ))}
      </ul>
      <div>Showing page {currentPage}</div>
    </div>
  );
};
 
export default Pagination;

8. Infinite Scroll

Overview: The Infinite Scroll challenge involves implementing a component that dynamically loads more items as the user scrolls down. This challenge helps practice handling asynchronous data loading and user interactions.

Core Functionality:

  • Load More Items: Fetch and display additional data on scroll.
  • Loading Indicator: Show a loading spinner or message while fetching data.

Example Implementation:

import React, { useState, useEffect, useCallback } from 'react';
 
const InfiniteScroll = () => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [page, setPage] = useState(1);
 
  const fetchItems = useCallback(async () => {
    setLoading(true);
    const response = await fetch(`https://api.example.com/items?page=${page}`);
    const newItems = await response.json();
    setItems(prevItems => [...prevItems, ...newItems]);
    setLoading(false);
    if (newItems.length === 0) {
      setHasMore(false);
    }
  }, [page]);
 
  useEffect(() => {
    fetchItems();
  }, [fetchItems]);
 
  const handleScroll = () => {
    if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight || loading) {
      return;
    }
    setPage(prevPage => prevPage + 1);
  };
 
  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, [handleScroll]);
 
  return (
    <div>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item.name}</li>
        ))}
      </ul>
      {loading && <div>Loading...</div>}
      {!hasMore && <div>No more items</div>}
    </div>
  );
};
 
export default InfiniteScroll;

Feel free to visit InterviewPro React (opens in a new tab) to explore these challenges in detail and see the implementations live.