Not able to set background image through react component, getting error

I have my background image ‘Sunny.jpg’ in public folder. I have written below code to set ‘Sunny.jpg’ as background image when end user enters location New York and press Enter but after pressing enter the background changes to the image ‘Sunny.jpg’ and immediately after that gives error

My Code

import React from 'react';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';

// Background images
//import SunnyImg from '../../Background Images/sunny.jpg';

// icons needed as per status
import { WiDaySunny } from "weather-icons-react";   // sun
import { WiMoonAltNew } from "weather-icons-react";  // moon
import { WiCloudy } from "weather-icons-react";  // cloud
import { WiRainWind } from "weather-icons-react";  // rain
import { WiThunderstorm } from "weather-icons-react";  // storm
import { WiSnowflakeCold } from "weather-icons-react";  // snow
import { WiDayHaze } from "weather-icons-react";  // Haze and Mist

import 'fontsource-roboto';

const WeatherStatus = (props) => {

    // Types of weather status "Clear","Clouds","Rain","Thunderstorm","Snow","Mist","Haze"

    return (
        <div>
            <Grid container justify="center">
                <Paper elevation={10} 
                    style={{ height:"auto", width:"45%", marginTop:"10%", padding:"3%", opacity:"75%" }} >
                    {props.status !== "Status" ? (
                        <Typography 
                            style={{ fontSize:25 }}
                            align="center"
                            spacing="justify"
                        >{
                            (props.status === "Clear" && props.time < 19) ? 
                                (<WiDaySunny className=".wb-font-style" size={35}/>)
                                (document.body.style.backgroundImage = "url(sunny.jpg)")
                            : (props.status === "Clear" && props.time >= 19 && props.time < 4) ? 
                                (<WiMoonAltNew className=".wb-font-style" size={35} />) 
                            : (props.status === "Clouds") ? 
                                (<WiCloudy className=".wb-font-style" size={35} />) 
                            : (props.status === "Rain") ? 
                                (<WiRainWind className=".wb-font-style" size={35} />) 
                            : (props.status === "Thunderstorm") ? 
                                (<WiThunderstorm className=".wb-font-style" size={35} />) 
                            : (props.status === "Snow") ? 
                                (<WiSnowflakeCold className=".wb-font-style" size={35} />) 
                            : (props.status === "Mist" || props.status === "Haze") ? 
                                (<WiDayHaze className=".wb-font-style" size={35} />)
                                (document.body.style.backgroundImage = "url(sunny.jpg)")
                            : ('')
                        }{props.status}</Typography>
                    ) : (
                        <Typography 
                            style={{ fontSize:25 }}
                            align="center"
                            spacing="justify"
                        >Status</Typography>
                    )}
                </Paper>
            </Grid>
        </div>
    )
}

export default WeatherStatus

I would suggest you move the logic of setting the background on the document out of the JSX. The ternary is responsible for returning a component.

You can make a function, or a component to deal with it. It might even return the components you want to render inside, instead of having everything inside a ternary in the JSX.

You can technically use an IIFE to write multi-line code (i.e, set background, then return element) in the JSX, but I wouldn’t suggest it.

Example
import React from "react";
import "./styles.css";
import First from "./components/First";
import Second from "./components/Second";

export default function App() {
  const [showFirst, setShowFirst] = React.useState(true);
  return (
    <div className="App">
      {
        (() => {
          if(showFirst) {
            document.body.style.backgroundImage = "url(first.jpg)";
            return <First />
          } else {
            document.body.style.backgroundImage = "url(second.jpg)";
            return <Second />
          }
        })()
      }
      <button onClick={() => setShowFirst(state => !state)}>Toggle</button>
    </div>
  );
}

Edit; BTW, why do your className values have dots . in front of them?

1 Like