Content is user-generated and unverified.

React & JavaScript Interview Questions with Answers

JavaScript Interview Questions (50 Total)

Foundational Questions (10)

1. What is JavaScript and what are its key features? JavaScript is a high-level, interpreted programming language primarily used for web development. Key features include:

  • Dynamic typing
  • First-class functions
  • Prototype-based object orientation
  • Event-driven programming
  • Asynchronous programming support
  • Cross-platform compatibility

2. What's the difference between var, let, and const?

  • var: Function-scoped, can be redeclared, hoisted with undefined initialization
  • let: Block-scoped, cannot be redeclared in same scope, hoisted but not initialized
  • const: Block-scoped, cannot be redeclared or reassigned, must be initialized at declaration

3. What is hoisting in JavaScript? Hoisting is JavaScript's behavior of moving variable and function declarations to the top of their containing scope during compilation. Variables declared with var are hoisted and initialized with undefined, while let and const are hoisted but not initialized (temporal dead zone).

4. Explain the difference between == and ===.

  • == (loose equality): Performs type coercion before comparison
  • === (strict equality): Compares values without type coercion, also compares types

5. What are JavaScript data types? Primitive types: number, string, boolean, undefined, null, symbol, bigint Non-primitive: object (including arrays, functions, dates, etc.)

6. What is the this keyword in JavaScript? this refers to the context in which a function is called. Its value depends on how the function is invoked:

  • Global context: window object (browser) or global object (Node.js)
  • Object method: the object itself
  • Constructor: the new instance
  • Arrow functions: inherit this from enclosing scope

7. What's the difference between null and undefined?

  • undefined: Variable declared but not assigned a value, or missing object property
  • null: Intentional absence of value, represents "no value" or "empty value"

8. What is a closure in JavaScript? A closure is a function that has access to variables in its outer (enclosing) scope even after the outer function has returned. It "closes over" variables from its lexical environment.

9. What are JavaScript events and event handling? Events are actions that occur in the browser (clicks, key presses, page loads). Event handling involves writing code that responds to these events using event listeners or inline event handlers.

10. What's the difference between synchronous and asynchronous JavaScript?

  • Synchronous: Code executes line by line, blocking subsequent code until current operation completes
  • Asynchronous: Non-blocking operations that allow other code to execute while waiting for completion (callbacks, promises, async/await)

Depth Questions (15)

11. Explain the JavaScript event loop. The event loop manages asynchronous operations in JavaScript. It consists of:

  • Call stack: Where function calls are stored
  • Web APIs: Browser-provided APIs (setTimeout, DOM events)
  • Callback queue: Where callbacks wait to be executed
  • Event loop: Monitors call stack and moves callbacks from queue to stack when empty

12. What are Promises and how do they work? Promises represent eventual completion or failure of asynchronous operations. They have three states: pending, fulfilled, rejected. They provide .then(), .catch(), and .finally() methods for handling results and support chaining.

13. Explain async/await and its advantages over Promises. Async/await is syntactic sugar over Promises that makes asynchronous code look synchronous. Advantages:

  • More readable and maintainable code
  • Better error handling with try/catch
  • Easier debugging
  • No callback hell or complex promise chains

14. What is prototypal inheritance? JavaScript uses prototype-based inheritance where objects can inherit properties and methods from other objects through the prototype chain. Every object has a __proto__ property pointing to its prototype.

15. Explain call, apply, and bind methods.

  • call(): Invokes function with specified this value and arguments
  • apply(): Similar to call but takes arguments as array
  • bind(): Returns new function with permanently bound this value

16. What are generator functions? Generator functions are special functions that can pause and resume execution using yield keyword. They return generator objects that implement iterator protocol.

17. Explain JavaScript modules (ES6). ES6 modules allow code organization into separate files with export and import statements. They provide static structure, compile-time optimization, and better dependency management.

18. What is debouncing and throttling?

  • Debouncing: Delays function execution until after a specified time has passed since last invocation
  • Throttling: Limits function execution to once per specified time interval

19. Explain WeakMap and WeakSet. WeakMap and WeakSet are collections that hold weak references to objects. Objects can be garbage collected if no other references exist, preventing memory leaks.

20. What is the Temporal Dead Zone? The period between entering a scope and the actual declaration of let or const variables where accessing the variable throws a ReferenceError.

21. Explain JavaScript's type coercion. Automatic conversion of values from one data type to another. Can be implicit (done by JavaScript engine) or explicit (done by developer using constructors like String(), Number()).

22. What are Symbols in JavaScript? Symbols are primitive data types that create unique identifiers. They're often used as object property keys to avoid naming conflicts and create private properties.

23. Explain the difference between deep and shallow copying.

  • Shallow copy: Copies only the first level of object properties
  • Deep copy: Recursively copies all levels of nested objects and arrays

24. What is currying in JavaScript? Currying transforms a function that takes multiple arguments into a series of functions that each take a single argument, enabling partial application.

25. Explain JavaScript's execution context. Execution context is the environment where JavaScript code is evaluated and executed. It contains variable environment, lexical environment, and this binding.

Code Snippet Questions (25)

26. What will this code output?

javascript
console.log(typeof null);
console.log(typeof undefined);
console.log(typeof []);

Answer: "object", "undefined", "object"

27. What's the output of this hoisting example?

javascript
console.log(x);
var x = 5;
console.log(x);

Answer: undefined, 5

28. What will this closure example print?

javascript
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}

Answer: 3, 3, 3 (due to closure capturing the final value of i)

29. Fix the above code to print 0, 1, 2:

javascript
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// OR
for (var i = 0; i < 3; i++) {
  setTimeout((j => () => console.log(j))(i), 100);
}

30. What's the output?

javascript
const obj = { a: 1 };
const obj2 = obj;
obj2.a = 2;
console.log(obj.a);

Answer: 2 (objects are passed by reference)

31. What will this print?

javascript
console.log(0.1 + 0.2 === 0.3);

Answer: false (floating-point precision issue)

32. Implement a simple debounce function:

javascript
function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

33. What's wrong with this code?

javascript
const arr = [1, 2, 3];
arr.forEach(async (item) => {
  const result = await processItem(item);
  console.log(result);
});
console.log('Done');

Answer: 'Done' will print before async operations complete. Use for...of with await or Promise.all().

34. Create a function that adds two numbers and can be called as add(2)(3):

javascript
function add(a) {
  return function(b) {
    return a + b;
  };
}
// OR arrow function version
const add = a => b => a + b;

35. What's the output?

javascript
const a = [1, 2, 3];
const b = [1, 2, 3];
console.log(a === b);
console.log(a == b);

Answer: false, false (different object references)

36. Implement array flattening:

javascript
function flatten(arr) {
  return arr.reduce((flat, item) => 
    flat.concat(Array.isArray(item) ? flatten(item) : item), []);
}
// OR using flat()
const flatten = arr => arr.flat(Infinity);

37. What's the output of this Promise chain?

javascript
Promise.resolve(1)
  .then(x => x + 1)
  .then(x => { throw new Error('Error') })
  .then(x => x + 1)
  .catch(err => 'Caught')
  .then(x => x + '!');

Answer: "Caught!"

38. Create a function to deep clone an object:

javascript
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof Array) return obj.map(item => deepClone(item));
  
  const cloned = {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloned[key] = deepClone(obj[key]);
    }
  }
  return cloned;
}

39. What does this code output?

javascript
function test() {
  console.log(this);
}
const obj = { test };
obj.test();
test();

Answer: obj (when called as method), window/global (when called as function)

40. Implement a simple EventEmitter:

javascript
class EventEmitter {
  constructor() {
    this.events = {};
  }
  
  on(event, callback) {
    if (!this.events[event]) this.events[event] = [];
    this.events[event].push(callback);
  }
  
  emit(event, ...args) {
    if (this.events[event]) {
      this.events[event].forEach(callback => callback(...args));
    }
  }
  
  off(event, callback) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(cb => cb !== callback);
    }
  }
}

41. What's the output?

javascript
const obj = {
  name: 'Object',
  getName: function() {
    return this.name;
  }
};
const getName = obj.getName;
console.log(getName());

Answer: undefined (this is not bound to obj)

42. Fix the above to maintain context:

javascript
const getName = obj.getName.bind(obj);
// OR
const getName = () => obj.getName();

43. Implement throttling:

javascript
function throttle(func, limit) {
  let inThrottle;
  return function(...args) {
    if (!inThrottle) {
      func.apply(this, args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

44. What's the output?

javascript
console.log([] + []);
console.log([] + {});
console.log({} + []);

Answer: "" (empty string), "[object Object]", "[object Object]"

45. Create a memoization function:

javascript
function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (key in cache) {
      return cache[key];
    }
    const result = fn.apply(this, args);
    cache[key] = result;
    return result;
  };
}

46. What happens here?

javascript
const promise1 = Promise.resolve(3);
const promise2 = new Promise(resolve => setTimeout(() => resolve('foo'), 1000));
const promise3 = Promise.reject('Error');

Promise.all([promise1, promise2, promise3])
  .then(values => console.log(values))
  .catch(error => console.log(error));

Answer: "Error" (Promise.all fails fast on first rejection)

47. Implement a function to check if object is empty:

javascript
function isEmpty(obj) {
  return Object.keys(obj).length === 0 && obj.constructor === Object;
}

48. What's the difference between these two?

javascript
function Person(name) {
  this.name = name;
  this.greet = function() {
    console.log(`Hi, I'm ${this.name}`);
  };
}

function Person(name) {
  this.name = name;
}
Person.prototype.greet = function() {
  console.log(`Hi, I'm ${this.name}`);
};

Answer: First creates new function for each instance, second shares method via prototype (more memory efficient).

49. Implement Promise.all manually:

javascript
function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    if (promises.length === 0) resolve([]);
    
    const results = [];
    let completed = 0;
    
    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then(value => {
          results[index] = value;
          completed++;
          if (completed === promises.length) {
            resolve(results);
          }
        })
        .catch(reject);
    });
  });
}

50. What's the output?

javascript
const arr = [1, 2, 3, 4, 5];
const result = arr.slice(1, 4).map(x => x * 2).filter(x => x > 4);
console.log(result);
console.log(arr);

Answer: [4, 6, 8], [1, 2, 3, 4, 5] (original array unchanged)


React Interview Questions (50 Total)

Foundational Questions (10)

1. What is React and what are its key features? React is a JavaScript library for building user interfaces, particularly web applications. Key features:

  • Component-based architecture
  • Virtual DOM for performance optimization
  • Unidirectional data flow
  • JSX syntax for writing components
  • Reusable components
  • Strong ecosystem and community support

2. What is JSX? JSX (JavaScript XML) is a syntax extension for JavaScript that allows writing HTML-like code within JavaScript. It gets transpiled to regular JavaScript function calls (React.createElement).

3. What's the difference between functional and class components?

  • Functional components: JavaScript functions that return JSX, simpler syntax, use hooks for state and lifecycle
  • Class components: ES6 classes extending React.Component, more verbose, use this.state and lifecycle methods

4. What are props in React? Props (properties) are read-only inputs passed from parent to child components. They allow data flow down the component tree and enable component reusability.

5. What is state in React? State is a built-in object that stores component data that can change over time. When state changes, the component re-renders to reflect the new data.

6. What are React Hooks? Hooks are functions that allow you to use state and other React features in functional components. They start with "use" (useState, useEffect, etc.).

7. What is the Virtual DOM? Virtual DOM is a JavaScript representation of the actual DOM kept in memory. React uses it to optimize rendering by comparing (diffing) the virtual DOM tree with the previous version and updating only changed elements.

8. What are keys in React lists? Keys are special attributes that help React identify which list items have changed, been added, or removed. They should be unique among siblings and stable across re-renders.

9. What is the difference between controlled and uncontrolled components?

  • Controlled: Form inputs whose values are controlled by React state
  • Uncontrolled: Form inputs that manage their own state internally, accessed via refs

10. What are React lifecycle methods? Lifecycle methods are special methods in class components that run at specific points in a component's life: mounting, updating, and unmounting phases.

Depth Questions (15)

11. Explain React's reconciliation process. Reconciliation is React's process of updating the DOM efficiently by comparing the new virtual DOM tree with the previous one, identifying differences, and applying minimal changes to the actual DOM.

12. What is Context API and when would you use it? Context API provides a way to share data between components without prop drilling. Use it for global data like themes, authentication, or language preferences that many components need access to.

13. Explain useEffect and its dependency array. useEffect handles side effects in functional components. The dependency array controls when the effect runs:

  • No array: runs after every render
  • Empty array: runs once after initial render
  • With dependencies: runs when dependencies change

14. What are Higher-Order Components (HOCs)? HOCs are functions that take a component and return a new enhanced component. They're used for code reuse, logic abstraction, and cross-cutting concerns like authentication or logging.

15. What is React.memo and when should you use it? React.memo is a higher-order component that memoizes functional components, preventing re-renders when props haven't changed. Use it for expensive components that receive the same props frequently.

16. Explain useMemo and useCallback hooks.

  • useMemo: Memoizes computed values to avoid expensive recalculations
  • useCallback: Memoizes function instances to prevent unnecessary re-renders of child components

17. What are React Portals? Portals provide a way to render children into a DOM node outside the parent component's DOM hierarchy, useful for modals, tooltips, or overlays.

18. Explain React's error boundaries. Error boundaries are components that catch JavaScript errors in their child component tree, log errors, and display fallback UI instead of crashing the entire application.

19. What is the difference between useState and useReducer?

  • useState: Simple state management for primitive values or simple objects
  • useReducer: Complex state management with predictable state transitions, similar to Redux pattern

20. Explain React's batching mechanism. React batches multiple state updates within event handlers into a single re-render for performance. In React 18, automatic batching extends to promises, timeouts, and native event handlers.

21. What are React Suspense and lazy loading? Suspense allows components to "wait" for something (like data or code) before rendering, showing fallback UI. React.lazy enables code splitting by dynamically importing components.

22. Explain the concept of lifting state up. Moving state from child components to their common parent component when multiple children need to share or synchronize the same state data.

23. What are React refs and when to use them? Refs provide access to DOM elements or component instances. Use them for focus management, text selection, media playback, or integrating with third-party libraries.

24. Explain React's StrictMode. StrictMode is a development tool that helps identify potential problems by running additional checks and warnings, including detecting unsafe lifecycles and deprecated APIs.

25. What is the React Fiber architecture? Fiber is React's reconciliation algorithm that enables incremental rendering, allowing React to pause, abort, or resume work to maintain responsive user interfaces.

Code Snippet Questions (25)

26. Create a counter component using useState:

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

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
}

27. What's wrong with this component?

jsx
function UserList({ users }) {
  return (
    <ul>
      {users.map(user => (
        <li>{user.name}</li>
      ))}
    </ul>
  );
}

Answer: Missing key prop. Should be <li key={user.id}>{user.name}</li>

28. Create a component that fetches data on mount:

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

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(userData => {
        setUser(userData);
        setLoading(false);
      });
  }, [userId]);
  
  if (loading) return <div>Loading...</div>;
  return <div>{user?.name}</div>;
}

29. Fix this component to prevent memory leaks:

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

function Timer() {
  const [seconds, setSeconds] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);
    
    return () => clearInterval(interval); // Cleanup function
  }, []);
  
  return <div>Seconds: {seconds}</div>;
}

30. Create a custom hook for localStorage:

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

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      return initialValue;
    }
  });
  
  const setStoredValue = (value) => {
    try {
      setValue(value);
      window.localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error(error);
    }
  };
  
  return [value, setStoredValue];
}

31. What will happen when button is clicked?

jsx
function App() {
  const [count, setCount] = useState(0);
  
  const handleClick = () => {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
  };
  
  return <button onClick={handleClick}>Count: {count}</button>;
}

Answer: Count increases by 1 (not 3) due to React batching and stale closure.

32. Fix the above to increment by 3:

jsx
const handleClick = () => {
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);
};

33. Create a Context for theme management:

jsx
import React, { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  
  const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };
  
  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within ThemeProvider');
  }
  return context;
}

34. Create a memoized expensive component:

jsx
import React, { memo, useMemo } from 'react';

const ExpensiveComponent = memo(({ items, multiplier }) => {
  const expensiveCalculation = useMemo(() => {
    return items.reduce((sum, item) => sum + item * multiplier, 0);
  }, [items, multiplier]);
  
  return <div>Result: {expensiveCalculation}</div>;
});

35. What's the issue with this useEffect?

jsx
function UserComponent({ userId }) {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    fetchUser(userId).then(setUser);
  }); // Missing dependency array
  
  return <div>{user?.name}</div>;
}

Answer: Infinite re-renders. Should have [userId] dependency array.

36. Create a form with controlled inputs:

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

function ContactForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });
  
  const handleChange = (e) => {
    setFormData(prev => ({
      ...prev,
      [e.target.name]: e.target.value
    }));
  };
  
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input
        name="name"
        value={formData.name}
        onChange={handleChange}
        placeholder="Name"
      />
      <input
        name="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="Email"
      />
      <textarea
        name="message"
        value={formData.message}
        onChange={handleChange}
        placeholder="Message"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

37. Create an error boundary component:

jsx
import React from 'react';

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }
  
  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }
  
  componentDidCatch(error, errorInfo) {
    console.error('Error caught by boundary:', error, errorInfo);
  }
  
  render() {
    if (this.state.hasError) {
      return (
        <div>
          <h2>Something went wrong.</h2>
          <button onClick={() => this.setState({ hasError: false, error: null })}>
            Try again
          </button>
        </div>
      );
    }
    
    return this.props.children;
  }
}

38. Implement a useDebounce hook:

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

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);
  
  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    
    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);
  
  return debouncedValue;
}

39. What's wrong with this component?

jsx
function TodoList() {
  const [todos, setTodos] = useState([]);
  
  const addTodo = (text) => {
    todos.push({ id: Date.now(), text, completed: false });
    setTodos(todos);
  };
  
  return (
    <div>
      {todos.map(todo => <div key={todo.id}>{todo.text}</div>)}
    </div>
  );
}

Answer: Mutating state directly. Should use setTodos([...todos, newTodo]).

40. Create a Portal component for modals:

jsx
import React from 'react';
import { createPortal } from 'react-dom';

function Modal({ children, isOpen, onClose }) {
  if (!isOpen) return null;
  
  return createPortal(
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-content" onClick={e => e.stopPropagation()}>
        {children}
        <button onClick={onClose}>Close</button>
      </div>
    </div>,
    document.getElementById('modal-root')
  );
}

41. Implement a usePrevious hook:

jsx
import { useRef, useEffect } from 'react';

function usePrevious(value) {
  const ref = useRef();
  
  useEffect(() => {
    ref.current = value;
  });
  
  return ref.current;
}

42. Create a component with lazy loading:

jsx
import React, { Suspense, lazy } from 'react';

const LazyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
      </Suspense>
    </div>
  );
}

43. What's the output when Parent re-renders?

jsx
const Child = ({ onClick }) => {
  console.log('Child rendered');
  return <button onClick={onClick}>Click me</button>;
};

function Parent() {
  const [count, setCount] = useState(0);
  
  const handleClick = () => {
    console.log('Clicked');
  };
  
  return (
    <div>
      <Child onClick={handleClick} />
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>
    </div>
  );
}

Answer: Child re-renders unnecessarily. Fix with useCallback or React.memo.

44. Fix the above with optimization:

jsx
const Child = React.memo(({ onClick }) => {
  console.log('Child rendered');
  return <button onClick={onClick}>Click me</button>;
});

function Parent() {
  const [count, setCount] = useState(0);
  
  const handleClick = useCallback(() => {
    console.log('Clicked');
  }, []);
  
  return (
    <div>
      <Child onClick={handleClick} />
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>
    </div>
  );
}

45. Create a higher-order component for authentication:

jsx
import React from 'react';

function withAuth(Component) {
  return function AuthenticatedComponent(props) {
    const [isAuthenticated, setIsAuthenticated] = useState(false);
    
    useEffect(() => {
      // Check authentication status
      checkAuthStatus().then(setIsAuthenticated);
    }, []);
    
    if (!isAuthenticated) {
      return <div>Please log in to access this content.</div>;
    }
    
    return <Component {...props} />;
  };
}

// Usage
const ProtectedComponent = withAuth(MyComponent);

46. Implement a useReducer counter:

jsx
import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return initialState;
    default:
      throw new Error('Unknown action type');
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

47. What's the issue with this effect cleanup?

jsx
function DataComponent() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    let cancelled = false;
    
    fetchData().then(result => {
      if (!cancelled) {
        setData(result);
      }
    });
    
    return () => {
      cancelled = true;
    };
  }, []);
  
  return <div>{data}</div>;
}

Answer: This is actually correct - it prevents setting state on unmounted components.

48. Create a compound component pattern:

jsx
import React, { createContext, useContext, useState } from 'react';

const AccordionContext = createContext();

function Accordion({ children, ...props }) {
  const [openIndex, setOpenIndex] = useState(null);
  
  return (
    <AccordionContext.Provider value={{ openIndex, setOpenIndex }}>
      <div {...props}>{children}</div>
    </AccordionContext.Provider>
  );
}

function AccordionItem({ children, index }) {
  const { openIndex, setOpenIndex } = useContext(AccordionContext);
  const isOpen = openIndex === index;
  
  return (
    <div>
      <button onClick={() => setOpenIndex(isOpen ? null : index)}>
        Toggle {index}
      </button>
      {isOpen && <div>{children}</div>}
    </div>
  );
}

Accordion.Item = AccordionItem;

// Usage
<Accordion>
  <Accordion.Item index={0}>Content 1</Accordion.Item>
  <Accordion.Item index={1}>Content 2</Accordion.Item>
</Accordion>

49. Implement a useAsync hook:

jsx
import { useState, useEffect, useCallback } from 'react';

function useAsync(asyncFunction, immediate = true) {
  const [status, setStatus] = useState('idle');
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  
  const execute = useCallback(() => {
    setStatus('pending');
    setData(null);
    setError(null);
    
    return asyncFunction()
      .then(response => {
        setData(response);
        setStatus('success');
      })
      .catch(error => {
        setError(error);
        setStatus('error');
      });
  }, [asyncFunction]);
  
  useEffect(() => {
    if (immediate) {
      execute();
    }
  }, [execute, immediate]);
  
  return { execute, status, data, error };
}

// Usage
function UserProfile({ userId }) {
  const {
    data: user,
    status,
    error,
    execute: refetch
  } = useAsync(() => fetchUser(userId));
  
  if (status === 'pending') return <div>Loading...</div>;
  if (status === 'error') return <div>Error: {error.message}</div>;
  
  return (
    <div>
      <h1>{user?.name}</h1>
      <button onClick={refetch}>Refresh</button>
    </div>
  );
}

50. Create a React component that implements infinite scrolling:

jsx
import React, { useState, useEffect, useCallback, useRef } from 'react';

function InfiniteScrollList() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [page, setPage] = useState(1);
  
  const observer = useRef();
  
  const lastElementRef = useCallback(node => {
    if (loading) return;
    if (observer.current) observer.current.disconnect();
    
    observer.current = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting && hasMore) {
        setPage(prevPage => prevPage + 1);
      }
    });
    
    if (node) observer.current.observe(node);
  }, [loading, hasMore]);
  
  useEffect(() => {
    const loadItems = async () => {
      setLoading(true);
      try {
        const response = await fetch(`/api/items?page=${page}`);
        const newItems = await response.json();
        
        setItems(prev => [...prev, ...newItems.data]);
        setHasMore(newItems.hasMore);
      } catch (error) {
        console.error('Error loading items:', error);
      } finally {
        setLoading(false);
      }
    };
    
    loadItems();
  }, [page]);
  
  return (
    <div>
      {items.map((item, index) => {
        if (items.length === index + 1) {
          return (
            <div ref={lastElementRef} key={item.id}>
              {item.title}
            </div>
          );
        }
        return <div key={item.id}>{item.title}</div>;
      })}
      {loading && <div>Loading more items...</div>}
      {!hasMore && <div>No more items to load</div>}
    </div>
  );
}

Behavioral and Conceptual Questions

React Architecture Questions

What are the best practices for React component organization?

  • Keep components small and focused on single responsibility
  • Use proper folder structure (components, hooks, utils, etc.)
  • Implement proper separation of concerns
  • Follow consistent naming conventions
  • Use TypeScript for better type safety
  • Implement proper error boundaries
  • Optimize performance with memoization when needed

How do you handle state management in large React applications?

  • Use Context API for global state that doesn't change frequently
  • Implement Redux or Zustand for complex state management
  • Keep local state in components when possible
  • Use custom hooks to encapsulate stateful logic
  • Consider state colocation principles
  • Implement proper data normalization

What are the performance optimization techniques in React?

  • Use React.memo for component memoization
  • Implement useMemo and useCallback for expensive operations
  • Use React.lazy and Suspense for code splitting
  • Optimize bundle size with tree shaking
  • Implement virtualization for large lists
  • Use proper key props in lists
  • Avoid inline object/function creation in render
  • Use production builds for deployment

JavaScript Architecture Questions

How do you handle asynchronous operations in JavaScript applications?

  • Use Promises for better error handling than callbacks
  • Implement async/await for cleaner asynchronous code
  • Handle promise rejections properly
  • Use Promise.all for concurrent operations
  • Implement proper error boundaries for async operations
  • Consider using libraries like RxJS for complex async flows

What are the JavaScript design patterns you commonly use?

  • Module pattern for encapsulation
  • Observer pattern for event handling
  • Factory pattern for object creation
  • Singleton pattern for global state
  • Strategy pattern for algorithm selection
  • Decorator pattern for extending functionality

This comprehensive guide covers the most important concepts and practical scenarios you'll encounter in React and JavaScript interviews. Practice these questions and understand the underlying concepts rather than memorizing answers.

Content is user-generated and unverified.
    React & JavaScript Interview Questions with Answers | Claude