Is it bad to use Refs to change styles in react?

2 min read 05-10-2024
Is it bad to use Refs to change styles in react?


Refs: Styling Friend or Foe? A Deep Dive into Best Practices

React's power lies in its declarative nature, encouraging developers to describe what they want, not how to achieve it. But what happens when you need fine-grained control over an element's style, particularly when you're not able to achieve it through traditional CSS or component props? This is where the humble ref often comes into play. However, the use of refs for styling can be a controversial topic.

The Scenario

Imagine a simple scenario where you want to change the background color of a div element based on user interaction. One common approach is to utilize a ref:

import React, { useState, useRef } from 'react';

function MyComponent() {
  const [isHovered, setIsHovered] = useState(false);
  const divRef = useRef(null);

  const handleMouseOver = () => {
    setIsHovered(true);
    divRef.current.style.backgroundColor = 'lightblue';
  };

  const handleMouseOut = () => {
    setIsHovered(false);
    divRef.current.style.backgroundColor = 'white';
  };

  return (
    <div 
      ref={divRef} 
      onMouseOver={handleMouseOver} 
      onMouseOut={handleMouseOut} 
      style={{ backgroundColor: isHovered ? 'lightblue' : 'white' }}
    >
      Hover me!
    </div>
  );
}

In this example, we use a ref to directly manipulate the backgroundColor style of the div element when the user hovers over it.

The Debate

While this might seem straightforward, there are valid concerns about using refs for styling. Here's why:

  • Breaking React's Declarative Nature: React thrives on describing the UI through components and props. Direct DOM manipulation, like using refs to change styles, goes against this principle, potentially leading to harder-to-manage and less predictable code.
  • Potential for Side Effects: Manipulating styles directly through refs can lead to unintended side effects, especially when dealing with complex components or multiple interactions.
  • CSS is the Way: For most styling scenarios, CSS is a more powerful, efficient, and predictable solution. CSS allows you to create reusable styles and easily apply them across your application, while refs often require individual element targeting.

Best Practices

So, should we completely avoid using refs for styling? Not necessarily. There are situations where it might be a suitable solution, but it should be a last resort. Here are some best practices:

  • Prioritize CSS: Explore CSS techniques like pseudo-classes (e.g., :hover), media queries, or conditional classes before resorting to refs.
  • Utilize State and Props: Use state and props to manage styling within components and leverage React's re-rendering mechanism for efficient style updates.
  • Ref for Layout: Consider using refs for layout-related scenarios where you need precise positioning or sizing of elements, but avoid using them for general styling.
  • CSS-in-JS: Libraries like styled-components offer a powerful alternative to traditional CSS, allowing you to write CSS within your components while maintaining React's declarative approach.

Conclusion

Using refs to change styles in React can be a tempting shortcut but often leads to less maintainable and less predictable code. The power of React lies in its declarative approach and leveraging its state management and component lifecycle. While refs have their place, especially for layout-related scenarios, prioritize CSS and CSS-in-JS solutions for styling whenever possible. Embrace React's philosophy and build a more robust and maintainable application.

Further Resources: