Modifying Body Attributes in React

Quick tutorial on how to add attributes to the <body> element within a React app. There are many use cases for this - the primary being to add a class (e.i. <body class="some--class">, and it works for any other attribute. The reason this is needed is because the <body> lies 'outside' most React apps.

The recommended setup for React is to add a <div> within a page's <body> where your root component will be rendered, like this:

<html>
  <head>
  </head>
  <body>
    <div id="root">
      <!-- Root Component -->
    </div>
  </body>
</html>

Add a class

There's nothing fancy here, it's just plain ole' Javascript, but in my experience from mentoring students I've seen many overlook regular Javascript when diving into React. To access the body from within React was can use document.body, and pair it with any other DOM manipulators. Using this:

document.body.classList.add('modal-open');

would add a modal-open class to the <body>. Similarly,

document.body.classList.remove('modal-open'); 

would remove the modal-open class from the <body>.

Any other DOM manipulation methods can be used with document.body. Here are a few examples:

document.body.id = 'newID';
document.body.style.fontSize = '20px';
document.body.dataset.someDataAttr = 'someValue';

Connecting to a Component

In my case I was implementing a modal into my app. When the modal opens it fills the entire screen with a semi-transparent background, and the modal content box. But scrolling was still enabled on the <body> behind the modal. To prevent this I needed to either:

  1. Add style="overflow: hidden;" to the body, or
  2. Add a class to the body which adds overflow: hidden;

I chose to go with #2, the class method. My modal element is contained within a standalone component within my app. When the modal is open I need to add a class to the <body> to prevent the page from scrolling, then remove the class when the modal is closed. Here's my stripped down component:

const MODAL_OPEN_CLASS = "body--modal-open";

class Modal extends Component {
  componentDidMount() {
    document.body.classList.add(MODAL_OPEN_CLASS);
  }

  componentWillUnmount() {
    document.body.classList.remove(MODAL_OPEN_CLASS);
  }

  render() {
    return (
      <div className="modal">
        <div className="modal__content"></div> 
      </div>
    )
  }
}

Now, when the Modal component is mounted the <body> has the body--modal-open classes added, and when the Modal component is unmounted the class is removed. And with some basic CSS targeting the .body--modal-open class I can prevent the page from scrolling while the modal is open.

Comments