0% found this document useful (0 votes)
7 views27 pages

Complete React Interview Preparation Guide

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)
7 views27 pages

Complete React Interview Preparation Guide

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/ 27

Complete React Interview Preparation Guide

1. How React Works Under the Hood (Explained Simply)


Think of React like a smart helper that builds websites using blocks (components). Here's how it works:

Virtual DOM: React creates a fake copy of your webpage in memory (like a blueprint)

Diffing: When something changes, React compares the old blueprint with the new one
Reconciliation: React only updates the parts that actually changed, making it super fast

Components: Everything is built with reusable pieces, like LEGO blocks

2. What Problem Did React Come to Solve?


Before React, developers faced these challenges:

DOM Manipulation: Manually updating HTML was slow and error-prone

State Management: Keeping track of data changes was complex


Reusability: Code was hard to reuse across different parts of an app

Performance: Updating entire pages was inefficient

React solved these by introducing:

Virtual DOM for efficient updates

Component-based architecture
Declarative programming (describe what you want, not how to do it)

Unidirectional data flow

3. Composable Components
Components that can be combined to build larger, more complex UIs:
javascript

// Small, focused components


const Button = ({ onClick, children }) => (
<button onClick={onClick}>{children}</button>
);

const Input = ({ value, onChange }) => (


<input value={value} onChange={onChange} />
);

// Composed into larger components


const LoginForm = () => {
const [username, setUsername] = useState('');
return (
<form>
<Input value={username} onChange={(e) => setUsername(e.target.value)} />
<Button onClick={handleLogin}>Login</Button>
</form>
);
};

4. Separating Logic and Style

CSS Modules

javascript

// styles.module.css
.button { background: blue; }

// Component.js
import styles from './styles.module.css';
const Button = () => <button className={styles.button}>Click me</button>;

Styled Components

javascript

import styled from 'styled-components';

const StyledButton = styled.button`


background: blue;
color: white;
`;
Custom Hooks for Logic

javascript

// useAuth.js (logic)
const useAuth = () => {
const [user, setUser] = useState(null);
const login = (credentials) => { /* logic */ };
return { user, login };
};

// Component.js (presentation)
const LoginButton = () => {
const { user, login } = useAuth();
return <button onClick={login}>Login</button>;
};

5. Security Measures in TypeScript Frontend

Input Validation

typescript

interface UserInput {
email: string;
password: string;
}

const validateInput = (input: UserInput): boolean => {


const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(input.email) && input.password.length >= 8;
};

Sanitization

typescript

import DOMPurify from 'dompurify';

const sanitizeHTML = (html: string): string => {


return DOMPurify.sanitize(html);
};

Secure API Calls


typescript

const apiCall = async (endpoint: string, data: any) => {


const token = localStorage.getItem('token');
return fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
};

6. Form Input Validation

Using Formik + Yup

javascript

import { Formik, Form, Field } from 'formik';


import * as Yup from 'yup';

const validationSchema = Yup.object({


email: Yup.string().email('Invalid email').required('Required'),
password: Yup.string().min(8, 'Too short').required('Required'),
});

const LoginForm = () => (


<Formik
initialValues={{ email: '', password: '' }}
validationSchema={validationSchema}
onSubmit={(values) => console.log(values)}
>
<Form>
<Field name="email" type="email" />
<Field name="password" type="password" />
<button type="submit">Submit</button>
</Form>
</Formik>
);

Custom Validation Hook


javascript

const useValidation = (value, rules) => {


const [error, setError] = useState('');

useEffect(() => {
const validateField = () => {
for (const rule of rules) {
if (!rule.test(value)) {
setError(rule.message);
return;
}
}
setError('');
};
validateField();
}, [value, rules]);

return error;
};

7. Typesafe Components Design

Generic Components

typescript

interface Props<T> {
data: T[];
renderItem: (item: T) => React.ReactNode;
keyExtractor: (item: T) => string;
}

const List = <T,>({ data, renderItem, keyExtractor }: Props<T>) => (


<ul>
{data.map(item => (
<li key={keyExtractor(item)}>{renderItem(item)}</li>
))}
</ul>
);

Union Types for Props


typescript

interface ButtonProps {
variant: 'primary' | 'secondary' | 'danger';
size: 'small' | 'medium' | 'large';
onClick: () => void;
children: React.ReactNode;
}

const Button: React.FC<ButtonProps> = ({ variant, size, onClick, children }) => (


<button className={`btn btn-${variant} btn-${size}`} onClick={onClick}>
{children}
</button>
);

8. Accessible Components

ARIA Attributes

javascript

const Modal = ({ isOpen, onClose, children }) => {


if (!isOpen) return null;

return (
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
<div className="modal-content">
<h2 id="modal-title">Modal Title</h2>
{children}
<button onClick={onClose} aria-label="Close modal">×</button>
</div>
</div>
);
};

Keyboard Navigation
javascript

const DropdownMenu = () => {


const [isOpen, setIsOpen] = useState(false);

const handleKeyDown = (e) => {


if (e.key === 'Escape') setIsOpen(false);
if (e.key === 'Enter' || e.key === ' ') setIsOpen(!isOpen);
};

return (
<div>
<button
onClick={() => setIsOpen(!isOpen)}
onKeyDown={handleKeyDown}
aria-expanded={isOpen}
aria-haspopup="true"
>
Menu
</button>
{isOpen && <ul role="menu">...</ul>}
</div>
);
};

9. State Management: Redux vs Context API

When to Use Context API


Simple, localized state
Small to medium applications
Minimal boilerplate needed

javascript

const ThemeContext = createContext();

const ThemeProvider = ({ children }) => {


const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
When to Use Redux

Complex state logic


Large applications

Time-travel debugging needed


Predictable state updates

javascript

// Redux store
const initialState = { count: 0 };

const counterReducer = (state = initialState, action) => {


switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};

10. State Management Options

Redux
Pros: Predictable, time-travel debugging, great DevTools
Cons: Boilerplate, learning curve

Use: Large apps, complex state logic

Context API
Pros: Built-in, simple, no extra dependencies

Cons: Performance issues with frequent updates


Use: Small to medium apps, simple state

MobX
Pros: Simple, less boilerplate, reactive

Cons: Less predictable, harder to debug


Use: When you prefer reactive programming

11. Hooks Deep Dive

useState
javascript

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

// Functional updates
setCount(prevCount => prevCount + 1);

// Lazy initialization
const [state, setState] = useState(() => {
return computeExpensiveValue();
});

useEffect

javascript

useEffect(() => {
// Side effect
const subscription = subscribeToSomething();

// Cleanup
return () => subscription.unsubscribe();
}, [dependency]); // Dependency array

Custom Hooks
javascript

const useLocalStorage = (key, initialValue) => {


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

const setValue = (value) => {


try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
};

return [storedValue, setValue];


};

12. Performance Optimization

React.memo

javascript

const ExpensiveComponent = React.memo(({ data }) => {


return <div>{/* Expensive rendering */}</div>;
});

// With custom comparison


const MyComponent = React.memo(({ user }) => {
return <div>{user.name}</div>;
}, (prevProps, nextProps) => {
return prevProps.user.id === nextProps.user.id;
});

useMemo
javascript

const ExpensiveComponent = ({ items }) => {


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

return <div>{expensiveValue}</div>;
};

useCallback

javascript

const Parent = ({ items }) => {


const handleClick = useCallback((id) => {
// Handle click
}, []);

return (
<div>
{items.map(item => (
<Child key={item.id} item={item} onClick={handleClick} />
))}
</div>
);
};

13. Server-Side Rendering and Next.js

Benefits of SSR
Better SEO
Faster initial page load

Better performance on slow devices

Next.js Features
javascript

// pages/index.js
export default function Home({ data }) {
return <div>{data.title}</div>;
}

// Static Site Generation


export async function getStaticProps() {
const data = await fetchData();
return { props: { data } };
}

// Server-Side Rendering
export async function getServerSideProps() {
const data = await fetchData();
return { props: { data } };
}

14. Testing React Components

Jest + React Testing Library

javascript

import { render, screen, fireEvent } from '@testing-library/react';


import Button from './Button';

test('renders button with text', () => {


render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});

test('calls onClick when clicked', () => {


const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);

fireEvent.click(screen.getByText('Click me'));
expect(handleClick).toHaveBeenCalledTimes(1);
});

Testing Hooks
javascript

import { renderHook, act } from '@testing-library/react';


import useCounter from './useCounter';

test('should increment counter', () => {


const { result } = renderHook(() => useCounter());

act(() => {
result.current.increment();
});

expect(result.current.count).toBe(1);
});

15. Component Lifecycle

Class Components

javascript

class MyComponent extends React.Component {


componentDidMount() {
// After component mounts
}

componentDidUpdate(prevProps, prevState) {
// After component updates
}

componentWillUnmount() {
// Before component unmounts
}

render() {
return <div>Hello</div>;
}
}

Functional Components (Hooks)


javascript

const MyComponent = () => {


useEffect(() => {
// componentDidMount
return () => {
// componentWillUnmount
};
}, []);

useEffect(() => {
// componentDidUpdate
});

return <div>Hello</div>;
};

16. React Router

Basic Setup

javascript

import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

const App = () => (


<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>

<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/users/:id" element={<User />} />
</Routes>
</BrowserRouter>
);

Navigation Hooks
javascript

import { useNavigate, useParams } from 'react-router-dom';

const User = () => {


const { id } = useParams();
const navigate = useNavigate();

const handleBack = () => navigate(-1);

return <div>User {id}</div>;


};

17. Error Boundaries

Class-based Error Boundary

javascript

class ErrorBoundary extends React.Component {


constructor(props) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError(error) {
return { hasError: true };
}

componentDidCatch(error, errorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
}

render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}

Usage
javascript

const App = () => (


<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);

18. PropTypes and TypeScript

PropTypes

javascript

import PropTypes from 'prop-types';

const Button = ({ text, onClick, variant }) => (


<button onClick={onClick} className={variant}>
{text}
</button>
);

Button.propTypes = {
text: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
variant: PropTypes.oneOf(['primary', 'secondary'])
};

TypeScript Integration

typescript

interface ButtonProps {
text: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
}

const Button: React.FC<ButtonProps> = ({ text, onClick, variant = 'primary' }) => (


<button onClick={onClick} className={variant}>
{text}
</button>
);

19. React Portals and Refs


Portals

javascript

import { createPortal } from 'react-dom';

const Modal = ({ children }) => {


return createPortal(
<div className="modal">
{children}
</div>,
document.getElementById('modal-root')
);
};

Refs

javascript

const FocusableInput = () => {


const inputRef = useRef(null);

const focusInput = () => {


inputRef.current?.focus();
};

return (
<div>
<input ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</div>
);
};

20. React Rendering Lifecycle

What Triggers Re-renders


State changes
Props changes

Parent component re-renders


Context value changes

Render Process
1. Trigger: Something causes a re-render
2. Render: React calls component functions
3. Commit: React applies changes to DOM

React Fiber Benefits


Incremental rendering

Ability to pause and resume work

Priority-based scheduling
Better error handling

21. Controlled vs Uncontrolled Components

Controlled Component

javascript

const ControlledInput = () => {


const [value, setValue] = useState('');

return (
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
};

Uncontrolled Component

javascript

const UncontrolledInput = () => {


const inputRef = useRef();

const handleSubmit = () => {


console.log(inputRef.current.value);
};

return (
<div>
<input ref={inputRef} defaultValue="initial" />
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
22. Reconciliation and React Fiber

Reconciliation Process
1. Compare new element tree with previous
2. Identify differences (diffing)

3. Update only changed parts


4. Maintain component state where possible

React Fiber Improvements


Incremental Rendering: Break work into chunks

Prioritization: High-priority updates first


Pausing: Pause work for browser painting

Error Boundaries: Better error handling

23. Performance Optimization Techniques

Code Splitting

javascript

import { lazy, Suspense } from 'react';

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

const App = () => (


<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);

Virtualization
javascript

import { FixedSizeList as List } from 'react-window';

const VirtualizedList = ({ items }) => (


<List
height={400}
itemCount={items.length}
itemSize={35}
>
{({ index, style }) => (
<div style={style}>
{items[index]}
</div>
)}
</List>
);

24. Higher-Order Components (HOCs)

Creating HOCs

javascript

const withLoading = (WrappedComponent) => {


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

// Usage
const EnhancedComponent = withLoading(MyComponent);

When to Use HOCs


Cross-cutting concerns
Reusable logic

Props manipulation

Conditional rendering

25. useEffect Dependency Array


No Dependency Array

javascript

useEffect(() => {
// Runs after every render
});

Empty Dependency Array

javascript

useEffect(() => {
// Runs only once after mount
}, []);

With Dependencies

javascript

useEffect(() => {
// Runs when dependencies change
}, [dependency1, dependency2]);

26. Context vs Redux

Use Context When


Simple state
Small to medium apps

Minimal boilerplate needed


Component tree is not too deep

Use Redux When


Complex state logic

Large applications
Time-travel debugging needed

Predictable state updates required

27. Preventing Memory Leaks

Cleanup in useEffect
javascript

useEffect(() => {
const subscription = subscribeToSomething();

return () => {
subscription.unsubscribe();
};
}, []);

Canceling Async Operations

javascript

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

const fetchData = async () => {


const result = await api.getData();
if (!isCancelled) {
setData(result);
}
};

fetchData();

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

28. Authentication and Security

JWT Handling
javascript

const useAuth = () => {


const [token, setToken] = useState(localStorage.getItem('token'));

const login = async (credentials) => {


const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials)
});

const { token } = await response.json();


setToken(token);
localStorage.setItem('token', token);
};

const logout = () => {


setToken(null);
localStorage.removeItem('token');
};

return { token, login, logout };


};

CSRF Protection

javascript

const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify(data)
});

29. Accessibility in React

ARIA Attributes
javascript

const AccessibleButton = ({ onClick, children, disabled }) => (


<button
onClick={onClick}
disabled={disabled}
aria-disabled={disabled}
aria-label={typeof children === 'string' ? children : 'Button'}
>
{children}
</button>
);

Focus Management

javascript

const Modal = ({ isOpen, onClose }) => {


const modalRef = useRef();

useEffect(() => {
if (isOpen && modalRef.current) {
modalRef.current.focus();
}
}, [isOpen]);

return isOpen ? (
<div
ref={modalRef}
role="dialog"
aria-modal="true"
tabIndex={-1}
>
Modal content
</div>
) : null;
};

Cross-Browser Compatibility

CSS Inconsistencies
css

/* Use CSS Reset */


*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

/* Vendor prefixes */
.rounded {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}

Polyfills

javascript

// Check if feature exists


if (!Array.prototype.includes) {
// Add polyfill
Array.prototype.includes = function(searchElement) {
return this.indexOf(searchElement) !== -1;
};
}

Debugging Browser Issues


Use browser DevTools

Check console for errors

Test in different browsers


Use feature detection libraries

Security Best Practices

Preventing XSS
javascript

// Don't use dangerouslySetInnerHTML with user input


const SafeComponent = ({ userInput }) => {
// This is safe - React escapes by default
return <div>{userInput}</div>;
};

// If you must use HTML, sanitize it


import DOMPurify from 'dompurify';

const UnsafeComponent = ({ htmlContent }) => {


const sanitizedHTML = DOMPurify.sanitize(htmlContent);
return <div dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />;
};

Handling CORS

javascript

// Frontend configuration
const apiCall = async (url, options) => {
const response = await fetch(url, {
...options,
credentials: 'include', // Include cookies
headers: {
'Content-Type': 'application/json',
...options.headers
}
});

return response.json();
};

Interview Tips

Common Questions to Prepare For


1. Explain the virtual DOM
2. What are hooks and why were they introduced?
3. How do you optimize React performance?

4. Difference between controlled and uncontrolled components


5. How does React handle state updates?

6. What is the purpose of keys in React lists?


7. How do you handle forms in React?

8. Explain the component lifecycle

Code Challenge Preparation


Practice building components from scratch
Understand async operations with useEffect

Know how to handle forms and validation


Practice state management patterns
Understand testing basics

Best Practices to Mention


Keep components small and focused
Use TypeScript for type safety

Implement proper error boundaries


Follow accessibility guidelines
Write tests for your components

Use meaningful component and variable names


Implement proper loading and error states

Remember: Practice coding examples, understand the "why" behind each concept, and be ready to
discuss trade-offs and alternatives!

You might also like