react.dev icon indicating copy to clipboard operation
react.dev copied to clipboard

React components should be pure, not "idempotent"

Open StevenBrons opened this issue 1 year ago • 3 comments

Summary

A blogpost in the React docs confuses idempotence with purity. Even though this might seem a small typo, it is one of essential importance in that blogpost.

Page

https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024

Details

Idempotence is a property of a function that it returns the same result if you apply the function twice to itself, for example, the absolute value function abs is idempotent, since, abs(abs(x)) = x. In general terms f : X --> X is idempotent iff f ∘ f = f.

This is confused with a pure function. This is a function that, given the same input, returns the same output. It is side-effect free or written in a "functional" style.

Even if this might seem like a minor mistake; it is one of the essential properties that the compiler should check for and to that extent, especially newer developers should not be confused.

StevenBrons avatar Jul 16 '24 15:07 StevenBrons

After some Google searching, I found a few other occurrences:

  • https://react.dev/reference/rules/components-and-hooks-must-be-pure
  • https://react.dev/reference/rules
  • https://react.dev/blog/2022/03/29/react-v18

StevenBrons avatar Jul 16 '24 15:07 StevenBrons

That's the definition that's used in mathematics. In computer science, the term is somewhat ambigious. E.g. we can find the definition you used (https://foldoc.org/idempotent) but also definitions that just mean "same result if called multiple times" (https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.2). Wikipedia uses the latter definition ("same result if called multiple times"): https://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning

React Hooks and Components must be pure and idempotent ("same result if called multiple times"): https://react.dev/reference/rules/components-and-hooks-must-be-pure#why-does-purity-matter

eps1lon avatar Jul 17 '24 10:07 eps1lon

TL;DR: I think the term "deterministic" more accurately reflects the concept that the React docs are talking about. A deterministic function is a function that "always produces the same output for the same input".

Full explanation

Unfortunately, React's usage of the term "idempotent" is not consistent with either of the Wikipedia definitions. Wikipedia's definitions of "idempotent function" f are:

  1. f(f(x)) == f(x)
  2. The computer's state after invoking f(); f() is the same as its state after invoking f(). In other words: additional calls to f do not change the computer's state any further.

From what I can tell, the React docs are simply mistaken about the meaning of the term. For example, the React reference manual says:

Components must always return the same output with respect to their inputs – props, state, and context. This is known as idempotency. Idempotency is a term popularized in functional programming. It refers to the idea that you always get the same result every time you run that piece of code with the same inputs.

As someone who has spent a few years in the Haskell community, I can confidently assert that the Haskell community doesn't talk about idempotency this way. Nor have I heard another FP community using that definition.

@eps1lon I think the confusion here is that the author of the React docs has confused:

  • "no additional effect if called multiple times", e.g. f(); f()

with:

  • "same return value if called multiple times", e.g. a = f(); b = f(); assert(a == b)

The latter property does not imply the former property, because in the second example, even if a == b, f might increment a global variable each time it is called. Therefore, React's definition is not compatible with the established meaning of idempotent.

I think the term "deterministic" more accurately reflects the concept that the React docs are talking about. If you Google "deterministic function", you will find that the established meaning is consistent with the property that the React docs care about.

nmsmith avatar May 12 '25 09:05 nmsmith