DEV Community

Mourya Vamsi Modugula
Mourya Vamsi Modugula

Posted on

Top 5 React.js Coding Challenges You Must Know for Interviews !

1. Build a Counter with React Hooks

Challenge: Write a simple React component that keeps track of how many times a button is clicked. Every time the button is pressed, the number should increase.

Task: Implement this using the useState hook.

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
};

export default Counter;
Enter fullscreen mode Exit fullscreen mode

Why This Matters: This is one of the most basic examples of state management in React. It demonstrates how to store, update, and display dynamic values with ease using hooks.

Pro Tip: How would you add a "Reset" button to set the count back to 0? Try it out!


2. Create a Form to Capture User Input

Challenge: Implement a form with two input fields—name and email. The values should update dynamically as the user types, and when the form is submitted, the entered data should appear on the screen.

import React, { useState } from 'react';

const UserForm = () => {
  const [formData, setFormData] = useState({
    name: '',
    email: ''
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prevData) => ({ ...prevData, [name]: value }));
  };

  return (
    <form>
      <input
        type="text"
        name="name"
        value={formData.name}
        onChange={handleChange}
        placeholder="Name"
      />
      <input
        type="email"
        name="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="Email"
      />
      <button type="submit">Submit</button>
    </form>
  );
};

export default UserForm;
Enter fullscreen mode Exit fullscreen mode

Why This Matters: Handling form input in React is a critical skill, especially for applications requiring user interactions, like login forms or search fields.

Pro Tip: How could you handle validation to ensure the email format is correct before allowing the form to submit?


3. Build a To-Do List with Add and Remove Functionality

Challenge: Create a to-do list where users can add tasks by typing into an input field and pressing "Add." Each task should have a "Remove" button to delete the task.

import React, { useState } from 'react';

const TodoList = () => {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState('');

  const addTodo = () => {
    if (newTodo.trim()) {
      setTodos([...todos, newTodo]);
      setNewTodo('');
    }
  };

  const removeTodo = (index) => {
    setTodos(todos.filter((_, i) => i !== index));
  };

  return (
    <div>
      <input
        type="text"
        value={newTodo}
        onChange={(e) => setNewTodo(e.target.value)}
        placeholder="Add a new task"
      />
      <button onClick={addTodo}>Add</button>

      <ul>
        {todos.map((todo, index) => (
          <li key={index}>
            {todo} <button onClick={() => removeTodo(index)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default TodoList;
Enter fullscreen mode Exit fullscreen mode

Why This Matters: Managing lists and state updates is a common task in React applications, especially for building dynamic user interfaces.

Pro Tip: What happens if you try to add an empty to-do item? How would you prevent that?


4. Implement Debouncing in a Search Input

Challenge: Build a search input that waits 500ms after the user stops typing before performing a search (simulated by updating the state). Use useEffect for this.

import React, { useState, useEffect } from 'react';

const Search = () => {
  const [query, setQuery] = useState('');
  const [searchTerm, setSearchTerm] = useState('');

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setSearchTerm(query);
    }, 500);

    return () => clearTimeout(timeoutId);
  }, [query]);

  return (
    <div>
      <input
        type="text"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Search..."
      />
      <p>Results for: {searchTerm}</p>
    </div>
  );
};

export default Search;
Enter fullscreen mode Exit fullscreen mode

Why This Matters: Debouncing is essential in search fields to prevent unnecessary API calls, improving performance and user experience.

Pro Tip: How could you improve this by adding a loading indicator while the user types?


5. Toggle Between "Hello" and "Goodbye" Messages

Challenge: Create a component that displays "Hello" or "Goodbye" based on a button toggle. Every time the button is clicked, the message should switch.

import React, { useState } from 'react';

const ToggleMessage = () => {
  const [showHello, setShowHello] = useState(true);

  return (
    <div>
      <p>{showHello ? 'Hello' : 'Goodbye'}</p>
      <button onClick={() => setShowHello(!showHello)}>
        Toggle Message
      </button>
    </div>
  );
};

export default ToggleMessage;
Enter fullscreen mode Exit fullscreen mode

Why This Matters: Conditional rendering is a core part of React's power, and this challenge helps solidify how to change what’s displayed based on state.

Pro Tip: How would you modify this so that it displays "Hello" in blue and "Goodbye" in red?


Bonus Challenge for the Curious:
For each of these components, how would you refactor the logic to separate concerns and make the code more reusable? Consider creating custom hooks where appropriate!


Top comments (0)