1. Introduction
React takes advantages of purity of components. A component in React should be written as Pure component.
In this short tutorial, we’ll discuss what is a pure component with an example. Before discussing pure component, let us discuss a pure function.
2. What is a pure function?
A pure function is a concept in computer science and functional programming that refers to a function with two main properties:
- Deterministic Output: Given the same input, a pure function will always produce the same output. This means that the function’s output depends exclusively on its input values, unaffected by any external or hidden states.
- No Side Effects: A pure function does not cause any observable side effects. Side effects are changes in the state of the system that occur outside the function itself, such as modifying global variables, changing the value of input parameters, writing to a file, or producing any form of output like printing to the console.
Following is a pure function:
function add(a, b) { return a + b; }
The method add
is a pure function because it will always return the same result based on the input values. For example, 2 + 3 will always be 5 no matter how many times the method is invoked with arguments 2 and 3. If you pass 2 and 3 as argument then the method will always return 5.
3. Pure components in React
React expects that every component you write is a pure function. This means that React components must always return the same JSX given the same inputs:
Following is an example of Pure component:
function Calculate({ input }) { return ( <div> Output for input {input} is {input * 2} </div> ); } export default function App() { return ( <> <Calculate input="2" /> <Calculate input="3" /> <Calculate input="5" /> </> ); }
4. Side Effects
React’s rendering process must always be pure. Components should strictly return their JSX without modifying any pre-existing objects or variables, as doing so would make them impure.
Following is an example of impure component. The method Calculate
reads and updates the variable initialValue
which is outside Calculate
. There is no guarantee that the same JSX will be returned based on the input values.
If other components read the value of guest then there is no guarantee that the same JSX will be returned.
let initialValue = 0; function Calculate({ input }) { initialValue = initialValue + 1; return ( <div> Output for input {input} is {input * 2 + initialValue} </div> ); } export default function App() { return ( <> <Calculate input="2" /> <Calculate input="3" /> <Calculate input="5" /> </> ); }
5. StrictMode and impure calculation detection
In React, you should never change preexisting variables or objects while your component is rendering. You should always treat props, state, and context as read-only. React provides a “Strict Mode” that calls each component’s function twice during development. This double invocation helps identify components that violate these rules.
Strict Mode does not impact performance in production, ensuring it won’t slow down your app for users. To enable Strict Mode, you can wrap your root component in . Some frameworks include this by default.
6. Local mutation in React component
You component should not update preexisting variables but a component can update local variables. A pure function should not mutate variables created before the function call.
So it’s fine to change variables and objects that you’ve just created while rendering.
function Double({ input }) { let initialValue = 5; initialValue = initialValue + 1; return ( <div> Double of {input} is {input * 2 + initialValue} </div> ); } export default function App() { return ( <> <Double input="2" /> <Double input="3" /> <Double input="5" /> </> ); }
Here, the initialValue
is created inside the function and updated later.
7. Where you can cause side effects?
While developing React application, you have to do certain things such as changing the data, starting an animation etc. Such changes are called side effects. In React, side effects are usually done inside event handlers.
Even though event handlers are defined inside your component, they don’t run during rendering. So event handlers don’t need to be pure.
8. Why does React need pure components?
Pure components provide several benefits:
- Your components might run in different environments, such as on the server! Because they produce the same result for the same inputs, a single component can handle numerous user requests.
- You can enhance performance by not rendering components whose inputs remain unchanged. This approach is safe because pure functions consistently return the same results, making them safe to cache.
- If some data changes during the rendering of a deep component tree, React can restart rendering without wasting time on the outdated render. Purity ensures that it is safe to stop calculations at any point.
9. Conclusion
Understanding and implementing pure components in React can significantly enhance the performance and maintainability of your applications. By ensuring that components always produce the same output for the same inputs and do not cause side effects, you create a more predictable and reliable codebase. This predictability makes debugging and testing easier, as well as allows for optimizations like skipping unnecessary renders and leveraging caching mechanisms. Incorporating pure components and adhering to functional programming principles will help you build efficient, robust, and scalable React applications.