Day 1: What Is a Pure Function? Why Should React Components Stay Pure?

Published on
4 mins read
--- views

When learning React, you’ve probably heard this line:

A React component should be a pure function.

But what exactly is a pure function? And why is it so important in React? Let’s start from the basics.


What Is a Pure Function?

A pure function has two key rules:

  1. Same input → always the same output
  2. No side effects

Example

// ✅ Pure function
function add(a, b) {
  return a + b;
}

// ❌ Not pure – changes something outside
let counter = 0;
function addAndCount(a, b) {
  counter++;
  return a + b;
}

The first one is predictable. The second one depends on an external variable, so it’s not pure.


Pure Functions in React

You can think of a React component like a math formula:

UI = f(state, props)
  • When props and state are the same, the UI should also be the same.
  • This makes it possible for React to compare the previous and next Virtual DOM and update only what has changed.

Why Does It Matter?

If your component is pure:

  • React knows “same input → same output.”
  • During the Virtual DOM diff, if the output hasn’t changed, React can skip real DOM updates, so the browser doesn’t repaint.
  • It’s easier to debug because the output is predictable.

⚠️ Note: A pure component doesn’t stop React from re-rendering the function. It only ensures that if the Virtual DOM output is the same, the real DOM won’t be updated. If you want to skip the re-render itself, you can use React.memo().

If your component is not pure:

  • It might return different UI even with the same props.
  • React won’t be able to optimize rendering correctly.
  • For example, calling fetch, Math.random(), or Date.now() directly inside render makes it impure.

React Render and Effect Flow

Render Phase (must stay pure):

  1. React calls the component function.
  2. It calculates the Virtual DOM based on props + state.
  3. React compares the new Virtual DOM with the previous one (diff).
  4. If they’re different → update real DOM. If they’re the same → skip update.

Effect Phase (handles side effects):

After rendering, React runs these hooks:

  • useEffect → for async side effects (API calls, event listeners)
  • useLayoutEffect → for sync DOM operations (reading size, adjusting layout)

👉 React forces side effects to live inside these hooks to keep the render phase pure. This ensures that the same props and state always produce the same UI.


Example: Pure vs Impure

Pure Component

function Hello({ name }) {
  return <h1>Hello {name}</h1>;
}

Same props.name → same UI every time.


Impure Component

let calls = 0;

function HelloCounter({ name }) {
  calls++; // changes external variable
  return <h1>Hello {name}, rendered {calls} times</h1>;
}

Even with the same props.name, the output changes — not pure. React can’t guarantee consistency here.


Quick Practice

Is this component pure?

function Greeting({ name }) {
  let upper = name.toUpperCase();
  return <h1>Hello {upper}</h1>;
}

Yes, it’s pure! upper is recalculated on every render, but as long as name stays the same, the output stays the same too.


Summary

  • Pure function → same input, same output, no side effects.
  • React render should stay pure → UI = f(state, props).
  • Side effects go into useEffect or useLayoutEffect.
  • A pure component can still re-render, but the Virtual DOM diff ensures the real DOM doesn’t update unnecessarily.
  • Keeping things pure makes React faster and more predictable.