Manipulating the body class attribute in react app’s is not straight forward, because of it’s nested components architecture. The workaround demonstrated in this article helps out.
A possible solution for changing the body-tag’s class attribute is manipulating document.body.class value directly in componentDidMount and componentDidUnmount. The drawback of using react’s lifecycle hooks is, they’re not available in function components. Also it’s a quite repetitive task.
A better solution is using the module react-side-effect to create a component that set’s the class value.
The core of this component is the withSideEffect HoC:
withSideEffect( reducePropsToState, handleStateChangeOnClient )(BodyCssClass)
The withSideEffect higher-order-component, calls reducePropsToState
with props
of each mounted instance when mounting, unmounting or receiving new props. We return some state aggregated from these props and handleStateChangeOnClient is called with this state. The latter function just manipulates the DOM element document.body.class
Full code of the component:
import { Component, Children } from 'react'; import PropTypes from 'prop-types'; import withSideEffect from 'react-side-effect'; // cssClass attribute is given the css class to be added to the body tag class BodyCssClass extends Component { render() { return this.props.children || null; } } BodyCssClass.propTypes = { cssClass: PropTypes.string.isRequired }; // reducePropsToState is called with props of each mounted instance const reducePropsToState = (propsList) => { let bodyCssClass = ''; propsList.forEach(function (props) { bodyCssClass = props.cssClass; }); return bodyCssClass; }; const handleStateChangeOnClient = (className) => { document.body.className = className }; export default withSideEffect( reducePropsToState, handleStateChangeOnClient )(BodyCssClass);
A create-react-app working demo example is available on https://github.com/lujakob/react-example-body-class
Also react-helmet is a very good option that provides additional possibilities for manipulating “head” tags from within components.