Sitemap

React interview guide

7 min readJan 29, 2025

--

React Concepts Guide

This guide covers fundamental and advanced React concepts, providing explanations and examples for each topic. Use this as a reference or learning resource for React development.

Table of Contents

  1. Basic React Concepts
  2. State and Props
  3. React Lifecycle
  4. React Hooks
  5. Advanced React Concepts
  6. State Management
  7. Performance Optimization
  8. React Router
  9. Testing React Applications
  10. Miscellaneous Concepts
  11. Practical Scenarios

Basic React Concepts

What is React?

React is a JavaScript library for building user interfaces. It was developed by Facebook and is widely used for creating interactive, fast, and scalable web applications.

Core Features and Benefits:

  1. Component-Based Architecture: React allows you to build encapsulated components that manage their own state.
  2. Virtual DOM: React uses a virtual representation of the DOM for efficient updates.
  3. JSX: A syntax extension for JavaScript that allows you to write HTML-like code in your JavaScript files.
  4. Unidirectional Data Flow: Data in React flows in one direction, from parent to child components.
  5. Large Ecosystem: React has a vast ecosystem of libraries and tools.

Key Features of React

Virtual DOM

The Virtual DOM is a lightweight copy of the actual DOM. React uses it to improve performance by minimizing direct manipulation of the DOM.

Example of how React updates the DOM:

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

In this example, when the button is clicked, React updates the Virtual DOM first, then efficiently updates only the changed parts in the real DOM.

JSX

JSX is a syntax extension for JavaScript that looks similar to XML or HTML. It allows you to write HTML structures in the same file as your JavaScript code.

Example:

const element = <h1>Hello, world!</h1>;

Components

Components are the building blocks of React applications. They can be either function components or class components.

Example of a function component:

function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}

Example of a class component:

class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}

Unidirectional Data Flow

Data in React flows in one direction, from parent to child components. This makes the application more predictable and easier to understand.

Example:

function ParentComponent() {
const [data, setData] = useState("Hello");
  return <ChildComponent message={data} />;
}
function ChildComponent({ message }) {
return <p>{message}</p>;
}

Functional vs Class Components

Functional Components

  • Simpler syntax
  • Use hooks for state and lifecycle features
  • Easier to test and debug

Example:

function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}

Class Components

  • Can use lifecycle methods
  • Can have local state
  • More verbose syntax

Example:

class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}

Lifecycle Methods and Hooks

Class components use lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount. Functional components use hooks like useEffect to achieve similar functionality.

Example with lifecycle methods:

class Example extends React.Component {
componentDidMount() {
console.log("Component mounted");
}
  componentWillUnmount() {
console.log("Component will unmount");
}
render() {
return <div>Example Component</div>;
}
}

Equivalent functional component with hooks:

function Example() {
useEffect(() => {
console.log("Component mounted");
return () => console.log("Component will unmount");
}, []);
  return <div>Example Component</div>;
}

What is JSX?

JSX is a syntax extension for JavaScript that allows you to write HTML-like code in your JavaScript files. It makes it easier to describe what the UI should look like.

Example:

const element = (
<div>
<h1>Hello!</h1>
<p>Welcome to React</p>
</div>
);

JSX is transformed into regular JavaScript function calls and objects before it’s run in the browser.

Virtual DOM vs Real DOM

The Virtual DOM is a lightweight copy of the actual DOM. When state changes occur, React creates a new Virtual DOM tree and compares it with the previous one. It then updates only the changed parts in the real DOM, which is more efficient than updating the entire DOM tree.

Benefits of Virtual DOM:

  1. Faster updates
  2. Improved performance
  3. More efficient than direct DOM manipulation

State and Props

State vs Props

State

  • Managed within the component
  • Can be changed over time
  • When state changes, the component re-renders

Example:

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

Props

  • Passed from parent to child components
  • Read-only within the component
  • Changes in props trigger re-renders

Example:

function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return <Welcome name="Alice" />;
}

Passing Data Between Components

Data is typically passed from parent to child components through props. For child-to-parent communication, you can pass functions as props.

Get Dileep Raloti’s stories in your inbox

Join Medium for free to get updates from this writer.

Example:

function Parent() {
const [message, setMessage] = useState("");
  const handleChildMessage = (childMessage) => {
setMessage(childMessage);
};
return (
<div>
<p>Message from child: {message}</p>
<Child onMessageSend={handleChildMessage} />
</div>
);
}
function Child({ onMessageSend }) {
return (
<button onClick={() => onMessageSend("Hello from child!")}>
Send Message to Parent
</button>
);
}

Modifying Props in Child Components

Props should not be modified directly in child components. They are considered read-only. If you need to modify data passed as props, you should lift the state up to a common ancestor.

Default Props

Default props provide fallback values for props that aren’t specified when a component is used.

Example:

function Greeting({ name = "Guest" }) {
return <h1>Hello, {name}!</h1>;
}
// Or for class components
Greeting.defaultProps = {
name: "Guest",
};

React Lifecycle

Class Component Lifecycle Methods

  1. Mounting:
  • constructor()
  • render()
  • componentDidMount()
  1. Updating:
  • render()
  • componentDidUpdate()
  1. Unmounting:
  • componentWillUnmount()

Example:

class LifecycleExample extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
  componentDidMount() {
console.log("Component mounted");
}
componentDidUpdate(prevProps, prevState) {
if (this.state.count !== prevState.count) {
console.log("Count updated");
}
}
componentWillUnmount() {
console.log("Component will unmount");
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}

Lifecycle Methods in Functional Components

Functional components use the useEffect hook to handle side effects and simulate lifecycle methods.

Example:

function LifecycleExample() {
const [count, setCount] = useState(0);
  useEffect(() => {
console.log("Component mounted");
return () => console.log("Component will unmount");
}, []); // Empty dependency array means this effect runs once on mount and cleanup on unmount
useEffect(() => {
console.log("Count updated");
}, [count]); // This effect runs when count changes
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

React Hooks

React Hooks were introduced in React 16.8 to allow functional components to use state and other React features without writing a class.

Common Hooks

  1. useState: Adds state to functional components
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
  1. useEffect: Performs side effects in functional components
function DataFetcher() {
const [data, setData] = useState(null);
  useEffect(() => {
fetch("https://api.example.com/data")
.then((response) => response.json())
.then((data) => setData(data));
}, []); // Empty dependency array means this effect runs once on mount
return <div>{data ? <p>{data}</p> : <p>Loading...</p>}</div>;
}
  1. useContext: Consumes a React context
const ThemeContext = React.createContext("light");
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>Themed Button</button>;
}
  1. useReducer: Manages complex state logic
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</div>
);
}

useEffect vs useLayoutEffect

  • useEffect runs asynchronously and after a render is painted to the screen.
  • useLayoutEffect runs synchronously after a render but before the screen is updated.

Use useLayoutEffect when you need to make DOM measurements or updates that should be synchronized with the browser's painting.

Custom Hooks

Custom hooks allow you to extract component logic into reusable functions.

Example:

function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return width;
}
function ResponsiveComponent() {
const width = useWindowWidth();
return <div>Window width is {width}</div>;
}

Advanced React Concepts

React Context

React Context provides a way to pass data through the component tree without having to pass props down manually at every level.

Example:

const ThemeContext = React.createContext("light");
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return <ThemedButton />;
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>Themed Button</button>;
}

Higher-Order Components (HOCs)

HOCs are functions that take a component and return a new component with some additional functionality.

Example:

function withLogging(WrappedComponent) {
return class extends React.Component {
componentDidMount() {
console.log(`Component ${WrappedComponent.name} mounted`);
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
const EnhancedComponent = withLogging(MyComponent);

React Portals

Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

Example:

function Modal({ children }) {
return ReactDOM.createPortal(children, document.getElementById("modal-root"));
}

Code Splitting

Code splitting allows you to split your code into small chunks which you can then load on demand.

Example using dynamic import:

const OtherComponent = React.lazy(() => import("./OtherComponent"));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}

React’s Reconciliation Process

Reconciliation is the process React uses to update the DOM. When a component’s state or props change, React creates a new virtual DOM tree and compares it with the previous one. It then updates the real DOM with the minimum number of changes necessary.

Prop Drilling

Prop drilling occurs when you pass props through multiple levels of components. It can be avoided by using React Context or state management libraries like Redux.

State Management

Redux

Redux is a predictable state container for JavaScript apps. It helps you write applications that behave consistently and are easy to test.

Core concepts of Redux:

  1. Store: Holds the state of your application
  2. Actions: Plain JavaScript objects that represent an intention to change the state
  3. Reducers: Pure functions that take the current state and an action, and return a new state

Example of a simple Redux setup:

// Action
const increment = () => ({ type: "INCREMENT" });
// Reducer
function counterReducer(state = 0, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
default:
return state;
}
}
// Store
const store = createStore(counterReducer);
// Usage
store.dispatch(increment());

--

--

Dileep Raloti
Dileep Raloti

Written by Dileep Raloti

0 followers

I'm a skilled React developer with a passion for building dynamic & user-friendly web applications. With expertise in JavaScript, HTML, CSS & other technology.