Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing style on <body> element

I am new to React so this may be simple but I cannot for the life of me find anything in the docs because the element is outside the ReactDOM.

I am using material-ui for the user interface and that provides two themes: lightBaseTheme (the default) and darkBaseTheme with darker colors. Sort of day and night modes. The problem is that neither apply any styling to the <body> so the page background does not follow the theme. The dark theme uses white text which does not show on the default white background.

I suspect that I need to find a programmatic solution and set the background color based on the currently loaded theme.

But how? I have tried putting code in the componentDidUpdate method of the top level component but that seems to always return the light theme. In any case I am not sure it is good practice to directly write to the DOM even though the body element is outside anything that is going to be affected by React.

export default class app extends React.Component {

    componentDidUpdate () {
        const muiTheme = getMuiTheme();
        const canvasColor = muiTheme.palette.canvasColor;
        document.body.style.backgroundColor = canvasColor;
    }

    render () {
        const muiTheme = getMuiTheme();
        return (
            <MuiThemeProvider muiTheme={getMuiTheme(darkBaseTheme)}>
                <span>Rest of the app goes here</span>
            </MuiThemeProvider>
        );
    }
};

The call to getMuiTheme in componentDidUpdate always returns lightBaseTheme even after it has been set in the render call.

I should perhaps add that the ultimate intention is to be able to change the theme on-the-fly so directly styling the <body element is not an option.

like image 869
amay Avatar asked Mar 11 '23 14:03

amay


1 Answers

If possible, the best solution would be to use a top level div inside your React app in addition to the style props to solve your issue.

However, what you have now won't work because componentDidUpdate() doesn't get called on initialization, and you don't seem to be having anything update it with props/state after loading.

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render. (React Docs)

Instead, use componentDidMount(), which is called as soon as the component mounts to your DOM.

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. Setting state in this method will trigger a re-rendering. (React Docs)

Here's a good write up on the component lifecycle.

like image 143
BradByte Avatar answered Mar 20 '23 09:03

BradByte