0% found this document useful (0 votes)
19 views20 pages

React - Js & JavaScript Interview Problems - 3+ Years Experience

Uploaded by

thamimansari358
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views20 pages

React - Js & JavaScript Interview Problems - 3+ Years Experience

Uploaded by

thamimansari358
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

React.

js & JavaScript Interview Problems - 3+ Years Experience


JavaScript Fundamentals

1. Closures and Scope

javascript

// Problem: What will this code output?


function outerFunction(x) {
return function innerFunction(y) {
return x + y;
};
}

const add5 = outerFunction(5);


console.log(add5(3)); // ?

// Answer: 8
// Explanation: The inner function has access to the outer function's variables (closure)

2. Hoisting

javascript

// Problem: What will this code output?


console.log(a); // ?
console.log(b); // ?
console.log(c); // ?

var a = 1;
let b = 2;
const c = 3;

// Answer:
// undefined (var is hoisted but not initialized)
// ReferenceError: Cannot access 'b' before initialization
// ReferenceError: Cannot access 'c' before initialization

3. Event Loop & Async


javascript

// Problem: What's the output order?


console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');

// Answer: 1, 4, 3, 2
// Explanation: Promises have higher priority than setTimeout in the event loop

4. Array Methods Implementation

javascript

// Problem: Implement your own map function


Array.prototype.myMap = function(callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}
return result;
};

// Usage
const numbers = [1, 2, 3, 4];
const doubled = numbers.myMap(x => x * 2);
console.log(doubled); // [2, 4, 6, 8]

5. Debouncing

javascript

// Problem: Implement a debounce function


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

// Usage
const debouncedSearch = debounce((query) => {
console.log('Searching for:', query);
}, 300);
6. Throttling

javascript

// Problem: Implement a throttle function


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

React Fundamentals

7. useState Hook

javascript

// Problem: Create a counter component with increment/decrement


import React, { useState } from 'react';

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

const increment = () => setCount(count + 1);


const decrement = () => setCount(count - 1);

return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}

8. useEffect Hook
javascript

// Problem: Fetch data and handle cleanup


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

function UserProfile({ userId }) {


const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
let isCancelled = false;

async function fetchUser() {


try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();

if (!isCancelled) {
setUser(userData);
setLoading(false);
}
} catch (error) {
if (!isCancelled) {
console.error('Error fetching user:', error);
setLoading(false);
}
}
}

fetchUser();

return () => {
isCancelled = true;
};
}, [userId]);

if (loading) return <div>Loading...</div>;


return <div>{user?.name}</div>;
}

9. Custom Hooks
javascript

// Problem: Create a custom hook for local storage


import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {


const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error('Error reading localStorage:', error);
return initialValue;
}
});

const setValue = (value) => {


try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error('Error setting localStorage:', error);
}
};

return [storedValue, setValue];


}

// Usage
function App() {
const [name, setName] = useLocalStorage('name', '');

return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
/>
);
}

10. Context API


javascript

// Problem: Create a theme context


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

const ThemeContext = createContext();

export function ThemeProvider({ children }) {


const [theme, setTheme] = useState('light');

const toggleTheme = () => {


setTheme(prevTheme => prevTheme === '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 a ThemeProvider');
}
return context;
}

// Usage
function App() {
const { theme, toggleTheme } = useTheme();

return (
<div className={`app ${theme}`}>
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'dark' : 'light'} mode
</button>
</div>
);
}

Intermediate React Patterns

11. Higher-Order Components (HOC)


javascript

// Problem: Create a HOC for loading states


import React from 'react';

function withLoading(WrappedComponent) {
return function WithLoadingComponent(props) {
if (props.isLoading) {
return <div>Loading...</div>;
}
return <WrappedComponent {...props} />;
};
}

// Usage
const UserList = ({ users }) => (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);

const UserListWithLoading = withLoading(UserList);

// In parent component
<UserListWithLoading users={users} isLoading={loading} />

12. Render Props Pattern


javascript

// Problem: Create a render props component for mouse tracking


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

function MouseTracker({ render }) {


const [position, setPosition] = useState({ x: 0, y: 0 });

useEffect(() => {
const handleMouseMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY });
};

window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);

return render(position);
}

// Usage
function App() {
return (
<MouseTracker
render={({ x, y }) => (
<div>Mouse position: {x}, {y}</div>
)}
/>
);
}

13. useReducer Hook


javascript
// Problem: Create a todo app with useReducer
import React, { useReducer } from 'react';

const initialState = { todos: [] };

function todoReducer(state, action) {


switch (action.type) {
case 'ADD_TODO':
return {
...state,
todos: [...state.todos, { id: Date.now(), text: action.payload, completed: false }]
};
case 'TOGGLE_TODO':
return {
...state,
todos: state.todos.map(todo =>
todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
)
};
case 'DELETE_TODO':
return {
...state,
todos: state.todos.filter(todo => todo.id !== action.payload)
};
default:
return state;
}
}

function TodoApp() {
const [state, dispatch] = useReducer(todoReducer, initialState);
const [inputValue, setInputValue] = useState('');

const addTodo = () => {


if (inputValue.trim()) {
dispatch({ type: 'ADD_TODO', payload: inputValue });
setInputValue('');
}
};

return (
<div>
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
/>
<button onClick={addTodo}>Add Todo</button>

{state.todos.map(todo => (
<div key={todo.id}>
<span
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
onClick={() => dispatch({ type: 'TOGGLE_TODO', payload: todo.id })}
>
{todo.text}
</span>
<button onClick={() => dispatch({ type: 'DELETE_TODO', payload: todo.id })}>
Delete
</button>
</div>
))}
</div>
);
}

Advanced React Concepts

14. useMemo and useCallback


javascript

// Problem: Optimize expensive calculations and prevent unnecessary re-renders


import React, { useState, useMemo, useCallback } from 'react';

function ExpensiveComponent({ items, onItemClick }) {


const expensiveValue = useMemo(() => {
console.log('Computing expensive value...');
return items.reduce((sum, item) => sum + item.value, 0);
}, [items]);

const handleClick = useCallback((item) => {


onItemClick(item);
}, [onItemClick]);

return (
<div>
<p>Total: {expensiveValue}</p>
{items.map(item => (
<button key={item.id} onClick={() => handleClick(item)}>
{item.name}
</button>
))}
</div>
);
}

// Parent component
function Parent() {
const [items, setItems] = useState([
{ id: 1, name: 'Item 1', value: 10 },
{ id: 2, name: 'Item 2', value: 20 }
]);
const [count, setCount] = useState(0);

const handleItemClick = useCallback((item) => {


console.log('Item clicked:', item);
}, []);

return (
<div>
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
<ExpensiveComponent items={items} onItemClick={handleItemClick} />
</div>
);
}
15. Error Boundaries

javascript

// Problem: Create an error boundary component


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>
<p>{this.state.error?.message}</p>
<button onClick={() => this.setState({ hasError: false, error: null })}>
Try again
</button>
</div>
);
}

return this.props.children;
}
}

// Usage
function App() {
return (
<ErrorBoundary>
<ComponentThatMightError />
</ErrorBoundary>
);
}
16. Lazy Loading and Suspense

javascript

// Problem: Implement lazy loading with Suspense


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

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

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

// LazyComponent.js
const LazyComponent = () => {
return <div>This component was loaded lazily!</div>;
};

export default LazyComponent;

Performance Optimization

17. React.memo
javascript

// Problem: Prevent unnecessary re-renders with React.memo


import React, { memo } from 'react';

const ExpensiveChildComponent = memo(({ name, value }) => {


console.log('ExpensiveChildComponent rendered');

return (
<div>
<p>{name}: {value}</p>
</div>
);
});

// With custom comparison


const OptimizedComponent = memo(({ user, settings }) => {
return (
<div>
<p>{user.name}</p>
<p>{settings.theme}</p>
</div>
);
}, (prevProps, nextProps) => {
return prevProps.user.id === nextProps.user.id &&
prevProps.settings.theme === nextProps.settings.theme;
});

18. Virtual Scrolling


javascript

// Problem: Implement basic virtual scrolling for large lists


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

function VirtualList({ items, itemHeight = 50, containerHeight = 400 }) {


const [scrollTop, setScrollTop] = useState(0);
const containerRef = useRef();

const startIndex = Math.floor(scrollTop / itemHeight);


const endIndex = Math.min(
startIndex + Math.ceil(containerHeight / itemHeight) + 1,
items.length
);

const visibleItems = items.slice(startIndex, endIndex);

const handleScroll = (e) => {


setScrollTop(e.target.scrollTop);
};

return (
<div
ref={containerRef}
style={{ height: containerHeight, overflow: 'auto' }}
onScroll={handleScroll}
>
<div style={{ height: items.length * itemHeight, position: 'relative' }}>
{visibleItems.map((item, index) => (
<div
key={startIndex + index}
style={{
position: 'absolute',
top: (startIndex + index) * itemHeight,
height: itemHeight,
width: '100%',
border: '1px solid #ccc'
}}
>
{item}
</div>
))}
</div>
</div>
);
}
Testing Questions

19. Unit Testing with Jest and React Testing Library

javascript

// Problem: Write tests for a component


import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import Counter from './Counter';

describe('Counter Component', () => {


test('renders initial count', () => {
render(<Counter />);
expect(screen.getByText('Count: 0')).toBeInTheDocument();
});

test('increments count when button is clicked', () => {


render(<Counter />);
const incrementButton = screen.getByText('+');
fireEvent.click(incrementButton);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});

test('decrements count when button is clicked', () => {


render(<Counter />);
const decrementButton = screen.getByText('-');
fireEvent.click(decrementButton);
expect(screen.getByText('Count: -1')).toBeInTheDocument();
});
});

Common Algorithm Problems

20. Flatten Array


javascript

// Problem: Flatten a nested array


function flattenArray(arr) {
return arr.reduce((flat, item) => {
return flat.concat(Array.isArray(item) ? flattenArray(item) : item);
}, []);
}

// Alternative with flat()


const flattenWithBuiltIn = (arr) => arr.flat(Infinity);

// Test
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(flattenArray(nested)); // [1, 2, 3, 4, 5, 6]

21. Deep Clone Object

javascript

// Problem: Deep clone an object


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));
if (typeof obj === 'object') {
const cloned = {};
Object.keys(obj).forEach(key => {
cloned[key] = deepClone(obj[key]);
});
return cloned;
}
}

// Test
const original = { a: 1, b: { c: 2, d: [3, 4] } };
const cloned = deepClone(original);
cloned.b.c = 999;
console.log(original.b.c); // 2 (unchanged)

22. Memoization
javascript

// Problem: Implement memoization for expensive functions


function memoize(fn) {
const cache = new Map();

return function(...args) {
const key = JSON.stringify(args);

if (cache.has(key)) {
return cache.get(key);
}

const result = fn.apply(this, args);


cache.set(key, result);
return result;
};
}

// Usage with Fibonacci


const fibonacci = memoize((n) => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});

Interview Tips

Key Areas to Focus On:


1. JavaScript Fundamentals: Closures, hoisting, event loop, promises
2. React Hooks: useState, useEffect, useContext, useReducer, useMemo, useCallback
3. Component Patterns: HOCs, render props, compound components

4. Performance: Memoization, lazy loading, virtual scrolling


5. Testing: Unit tests, integration tests, mocking

6. State Management: Context API, Redux patterns


7. Error Handling: Error boundaries, try-catch blocks

8. Async Operations: Fetch, axios, handling loading states

Common Follow-up Questions:


"How would you optimize this component?"
"What are the trade-offs of this approach?"

"How would you test this functionality?"


"What happens if this API call fails?"
"How would you handle this at scale?"

Practice Strategy:
1. Start with JavaScript fundamentals

2. Build small React components from scratch

3. Implement common patterns and hooks


4. Focus on performance optimization techniques
5. Practice explaining your thought process

6. Learn to identify and handle edge cases

Remember: Interviewers want to see your problem-solving approach, not just the final solution. Always
explain your thinking process!

You might also like