16 Nov 2021
A Visual Guide to React Rendering - Refs
How can we disable this button after 3 clicks without re-rendering the component for the first 2 clicks?
Storing values with refs
When you want a component to “remember” some information, but you don’t want that information to trigger new renders, you can use a ref—it’s like a secret “pocket” for storing information in your component!
Let's try counting clicks with refs instead of state.
The ref updates, but the button is still active. Why is that?
Component renders and DOM updates
For React to disable the button, it needs to update the DOM. React updates the DOM when a component renders with different output than before. React won't update any DOM until one of its components renders. Since changing a ref doesn't cause the component to re-render, the button stays active.
To demonstrate this point further, let's add a parent component.
By default, when you render a React component, it recursively re-renders all its children. That's why when we update the Parent
state, it renders both Parent
and Component
. When Component
renders, React executes the condition and disables the button.
However, we can't rely on parent updates to disable a button. Let's implement this behavior directly in Component
.
Update state to re-render a component
We can make the component re-render by reintroducing state. But we still don't want the component to render on the first 2 clicks. So we'll keep the ref to silently count the clicks, and we'll add a state variable with the sole responsibility of updating the button status. Let's update buttonStatus
only when the button is clicked for the third time.
This example demonstrates the behavior of refs. Keep in mind that unnecessary renders aren't always bad, and you don't have to eliminate every one of them. In fact, in a real-world scenario, it would probably make more sense to rely solely on state and re-render this component 3 times for simplicity. However, you'll encounter various situations in your apps. Understanding refs gives you a powerful tool for fine-tuning the behavior of your components.