React.
js Interview Preparation - Wissen Technology
1. useMemo and useCallback - What's the difference?
useMemo: Memoizes computed values to avoid expensive recalculations useCallback: Memoizes
functions to prevent unnecessary re-renders
javascript
// useMemo - memoizes the result of expensive calculation
const ExpensiveComponent = ({ items }) => {
const expensiveValue = useMemo(() => {
return items.reduce((sum, item) => sum + item.price, 0);
}, [items]); // Only recalculates when items change
return <div>Total: {expensiveValue}</div>;
};
// useCallback - memoizes the function itself
const Parent = ({ items }) => {
const handleClick = useCallback((id) => {
// Handle click logic
console.log(id);
}, []); // Function reference stays same
return (
<div>
{items.map(item =>
<Child key={item.id} onClick={handleClick} />
)}
</div>
);
};
Key Difference: useMemo returns a memoized value, useCallback returns a memoized function.
2. Multiple API Calls in Parallel - Promise.all()
javascript
const fetchAllData = async () => {
try {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(res => res.json()),
fetch('/api/posts').then(res => res.json()),
fetch('/api/comments').then(res => res.json())
]);
setUsers(users);
setPosts(posts);
setComments(comments);
} catch (error) {
console.error('One or more requests failed:', error);
}
};
// In React component
useEffect(() => {
fetchAllData();
}, []);
Why Promise.all(): Executes all API calls simultaneously, faster than sequential calls.
3. Handle Frequent API Calls - Debouncing
javascript
import { useState, useEffect, useCallback } from 'react';
const SearchComponent = () => {
const [searchTerm, setSearchTerm] = useState('');
const [results, setResults] = useState([]);
// Debounce function
const debounce = (func, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(null, args), delay);
};
};
const searchAPI = async (query) => {
if (!query) return;
const response = await fetch(`/api/search?q=${query}`);
const data = await response.json();
setResults(data);
};
const debouncedSearch = useCallback(debounce(searchAPI, 500), []);
useEffect(() => {
debouncedSearch(searchTerm);
}, [searchTerm, debouncedSearch]);
return (
<div>
<input
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search..."
/>
{/* Render results */}
</div>
);
};
4. Tree Shaking
Definition: Eliminates unused code from your final bundle.
javascript
// utils.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export const multiply = (a, b) => a * b;
// main.js
import { add } from './utils.js'; // Only 'add' is included in bundle
// subtract and multiply are "shaken off" (removed) from final bundle
Benefits: Smaller bundle size, faster load times.
5. Bundlers
Definition: Tools that combine multiple files into optimized bundles for production.
Popular Bundlers:
Webpack: Most popular, highly configurable
Vite: Modern, fast development server
Rollup: Focused on ES modules
Parcel: Zero-configuration bundler
6. Challenging Feature - Persistent Filters
javascript
// Custom hook for persistent filters
const usePersistentFilters = (key) => {
const [filters, setFilters] = useState(() => {
const saved = localStorage.getItem(key);
return saved ? JSON.parse(saved) : {};
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(filters));
}, [filters, key]);
return [filters, setFilters];
};
// Usage in component
const ProductList = () => {
const [filters, setFilters] = usePersistentFilters('product-filters');
const handleFilterChange = (filterType, value) => {
setFilters(prev => ({
...prev,
[filterType]: value
}));
};
// Filters persist even after page reload
};
7. React Bundlers, Compilers, and Transpilers
Bundlers: Webpack, Vite, Rollup (combine files) Compilers: Babel (transforms modern JS to compatible
JS) Transpilers: TypeScript compiler, Babel (converts one language to another)
React's Built-in: React has JSX transformer, but external tools needed for full compilation.
8. String Compression Problem (from image)
javascript
function compressString(s) {
if (!s) return s;
let compressed = '';
let count = 1;
for (let i = 0; i < s.length; i++) {
if (i + 1 < s.length && s[i] === s[i + 1]) {
count++;
} else {
compressed += s[i] + (count > 1 ? count : '');
count = 1;
}
}
return compressed.length < s.length ? compressed : s;
}
// Examples:
// "aabcccccaaa" → "a2bc5a3"
// "abcde" → "abcde" (no compression)
9. Unit Testing in React
javascript
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
describe('Counter Component', () => {
test('renders initial count of 0', () => {
render(<Counter />);
expect(screen.getByText('Count: 0')).toBeInTheDocument();
});
test('increments count when button clicked', () => {
render(<Counter />);
const button = screen.getByText('Increment');
fireEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
});
Tools: Jest, React Testing Library, Enzyme (legacy)
10. Version Migration in React
Common Migration Steps:
1. Update package.json dependencies
2. Review breaking changes in changelog
3. Update deprecated APIs (componentWillMount → useEffect)
4. Test functionality thoroughly
5. Update testing dependencies
javascript
// React 16 → 18 migration example
// Old: ReactDOM.render
ReactDOM.render(<App />, document.getElementById('root'));
// New: createRoot
const root = createRoot(document.getElementById('root'));
root.render(<App />);
11. Async Operations in Redux
Redux Toolkit (recommended):
javascript
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
// Async thunk
export const fetchUsers = createAsyncThunk(
'users/fetchUsers',
async () => {
const response = await fetch('/api/users');
return response.json();
}
);
// Slice
const usersSlice = createSlice({
name: 'users',
initialState: { data: [], loading: false, error: null },
extraReducers: (builder) => {
builder
.addCase(fetchUsers.pending, (state) => {
state.loading = true;
})
.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchUsers.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
}
});
12. Stopwatch Timer Component
javascript
import { useState, useEffect, useRef } from 'react';
const Stopwatch = () => {
const [time, setTime] = useState(0);
const [isRunning, setIsRunning] = useState(false);
const intervalRef = useRef(null);
useEffect(() => {
if (isRunning) {
intervalRef.current = setInterval(() => {
setTime(prevTime => prevTime + 10);
}, 10);
} else {
clearInterval(intervalRef.current);
}
return () => clearInterval(intervalRef.current);
}, [isRunning]);
const formatTime = (time) => {
const minutes = Math.floor(time / 60000);
const seconds = Math.floor((time % 60000) / 1000);
const milliseconds = Math.floor((time % 1000) / 10);
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.${milliseconds.toString().padStart(2, '0
};
const handleStart = () => setIsRunning(true);
const handlePause = () => setIsRunning(false);
const handleReset = () => {
setTime(0);
setIsRunning(false);
};
return (
<div>
<h1>{formatTime(time)}</h1>
<button onClick={handleStart} disabled={isRunning}>Start</button>
<button onClick={handlePause} disabled={!isRunning}>Pause</button>
<button onClick={handleReset}>Reset</button>
</div>
);
};
13. Prototype Functions
javascript
// String prototype example
String.prototype.reverse = function() {
return this.split('').reverse().join('');
};
// Usage
const str = "hello";
console.log(str.reverse()); // "olleh"
// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
const person1 = new Person("John", 30);
console.log(person1.greet()); // "Hello, I'm John"
14. Hooks Used & Differences
Common Hooks:
useState: Manages component state
useEffect: Side effects (API calls, subscriptions)
useContext: Access context values
useReducer: Complex state management
useMemo: Memoize expensive calculations
useCallback: Memoize functions
useCallback vs useMemo:
useCallback: Returns memoized function
useMemo: Returns memoized value
15. Duplicate Keys in map() - Side Effects
javascript
// ❌ Bad - Duplicate keys
const items = [
{ id: 1, name: 'Item 1' },
{ id: 1, name: 'Item 2' }, // Duplicate key!
];
return items.map(item => <div key={item.id}>{item.name}</div>);
Side Effects:
React can't differentiate between elements
Incorrect re-rendering behavior
State may not update correctly
Performance issues
Console warnings
16. React Compiler
Babel: Most common React compiler
Transforms JSX to JavaScript
Not built into React
Handles modern JS features
javascript
// JSX (before compilation)
const element = <h1>Hello, World!</h1>;
// Compiled JavaScript
const element = React.createElement('h1', null, 'Hello, World!');
Without JSX: You don't need Babel if using React.createElement directly.
17. Promises
javascript
// Promise creation
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve({ data: 'Success!' });
} else {
reject(new Error('Failed to fetch'));
}
}, 1000);
});
};
// Promise usage
fetchData()
.then(result => console.log(result))
.catch(error => console.error(error));
// Async/await
const getData = async () => {
try {
const result = await fetchData();
console.log(result);
} catch (error) {
console.error(error);
}
};
18. Checkerboard Implementation
javascript
const Checkerboard = ({ size = 8 }) => {
const createBoard = () => {
const board = [];
for (let row = 0; row < size; row++) {
const currentRow = [];
for (let col = 0; col < size; col++) {
const isBlack = (row + col) % 2 === 1;
currentRow.push(isBlack);
}
board.push(currentRow);
}
return board;
};
const board = createBoard();
return (
<div style={{ display: 'inline-block' }}>
{board.map((row, rowIndex) => (
<div key={rowIndex} style={{ display: 'flex' }}>
{row.map((isBlack, colIndex) => (
<div
key={colIndex}
style={{
width: 50,
height: 50,
backgroundColor: isBlack ? 'black' : 'white',
border: '1px solid gray'
}}
/>
))}
</div>
))}
</div>
);
};
19. Shared Redux Store Between Modules
javascript
// store.js
import { configureStore } from '@reduxjs/toolkit';
import userSlice from './features/userSlice';
import productSlice from './features/productSlice';
export const store = configureStore({
reducer: {
users: userSlice,
products: productSlice,
},
});
// App.js
import { Provider } from 'react-redux';
import { store } from './store';
function App() {
return (
<Provider store={store}>
<UserModule />
<ProductModule />
</Provider>
);
}
20. Debounce Explanation
Definition: Delays function execution until after a specified time has passed since the last call.
javascript
const debounce = (func, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(null, args), delay);
};
};
// Usage in search
const debouncedSearch = debounce((query) => {
// API call here
searchAPI(query);
}, 500); // Wait 500ms after user stops typing
21. Search Input - Promise Handling
AbortController is most appropriate for search scenarios:
javascript
const SearchComponent = () => {
const [query, setQuery] = useState('');
const abortControllerRef = useRef(null);
useEffect(() => {
const searchData = async () => {
// Cancel previous request
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
// Create new abort controller
abortControllerRef.current = new AbortController();
try {
const response = await fetch(`/api/search?q=${query}`, {
signal: abortControllerRef.current.signal
});
const data = await response.json();
setResults(data);
} catch (error) {
if (error.name !== 'AbortError') {
console.error('Search failed:', error);
}
}
};
if (query) {
const timeoutId = setTimeout(searchData, 300);
return () => clearTimeout(timeoutId);
}
}, [query]);
};
22. React Version & Migration
Current Version Used: React 18 Migration Experience: Yes, migrated from Create React App to Vite
Why Vite over Create React App:
Faster development server (ES modules)
Faster builds (esbuild)
Better performance
More flexibility
Active development (CRA is deprecated)
javascript
// Vite config example
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
},
build: {
outDir: 'build',
},
});
23. Redux Async Operations
Redux doesn't handle async by default. Tools used:
Redux Toolkit (createAsyncThunk)
Redux Thunk (middleware)
Redux Saga (for complex async flows)
Can't call API in reducer: Reducers must be pure functions. Use middleware or thunks.
24. Redux vs Context API
Use Redux when:
Complex state management
Time-travel debugging needed
Multiple components need same state
State logic is complex
Use Context when:
Simple state sharing
Theme/user preferences
Small to medium applications
25. Constructor Function
javascript
function Car(make, model) {
this.make = make;
this.model = model;
this.start = function() {
console.log(`${this.make} ${this.model} is starting`);
};
}
const myCar = new Car('Toyota', 'Camry');
myCar.start(); // "Toyota Camry is starting"
26. Previous Project Features
Azure Translation with i18n:
javascript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
// Configuration for 6+ languages
i18n.use(initReactI18next).init({
resources: {
en: { translation: require('./locales/en.json') },
es: { translation: require('./locales/es.json') },
fr: { translation: require('./locales/fr.json') },
// ... other languages
},
lng: 'en',
fallbackLng: 'en',
});
// Azure Translator integration
const translateText = async (text, targetLang) => {
const response = await fetch('/api/translate', {
method: 'POST',
body: JSON.stringify({ text, to: targetLang }),
});
return response.json();
};
Stripe Payment Integration:
javascript
import { loadStripe } from '@stripe/stripe-js';
import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe('pk_test_...');
const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
event.preventDefault();
const { error, paymentIntent } = await stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: elements.getElement(CardElement),
}
}
);
if (!error) {
console.log('Payment successful!');
}
};
};
27. Code Quality Assurance
Methods to ensure no impact on existing functionality:
1. Unit Tests: Test individual components
2. Integration Tests: Test component interactions
3. Regression Testing: Test existing features
4. Code Reviews: Team review process
5. Feature Flags: Gradual rollout
6. Staging Environment: Test before production
javascript
// Example test
describe('New Feature', () => {
test('should not break existing login functionality', () => {
render(<LoginComponent />);
// Test existing login still works
});
});
28. Company Knowledge & Personal Questions
About Wissen Technology: Research the company's:
Core services (IT consulting, development)
Technologies they work with
Recent projects or achievements
Company culture and values
Why hire you: "I bring strong React.js expertise with hands-on experience in modern development
practices. My experience with complex features like persistent filters, payment integration, and multi-
language support demonstrates my ability to deliver business-critical solutions. I'm passionate about
writing clean, testable code and staying updated with the latest React ecosystem."
5-year vision: "I see myself as a senior full-stack developer, potentially leading a team and mentoring
junior developers. I want to deepen my expertise in React ecosystem and explore emerging technologies
like Next.js, React Server Components, and modern deployment strategies."
Key Interview Tips:
1. Be Specific: Use concrete examples from your experience
2. Explain Your Thinking: Walk through your problem-solving process
3. Ask Questions: Show interest in their tech stack and challenges
4. Practice Coding: Be ready to code live during the interview
5. Stay Calm: Take your time to think through answers
Good luck with your interview! 🚀