Background Image flickering when change - react

别来无恙 提交于 2020-05-16 05:54:13

问题


I have been rewriting my website ondeband.com - it is currently a wordpress website and I am about a month into writing it in react.

I am not going to change the home page too much - it has a background image that changes every couple seconds. You can see it in my link above.

Problem is...on my new react version of the website - it flickers between each image change - speically when I pushed it to heroku. It works 99% of time on my local dev server.

I have a feeling it is due to the 'preloading' of the images? Maybe you can point me in the right direction - Here is my code for the home page of my app.

The div with the className of 'homePage' is where the bg image is loaded into the inline styles. The variable bgImage is stored in state. I use the useEffect hook to start the function, 'bgTransition', that changes each image randomly.

    import React, { useState, useEffect } from "react";
import NavBarA from "./components/NavBarA";
import { Router, Route, Switch } from "react-router-dom";
import BookABand2 from "./components/Profile/BookABand2";
import LiveProfile from './components/BookABand/LiveProfile'
import Account from './components/Account/Account'
import history from "./uitls/history";
import PrivateRoute from "./components/PrivateRoute";
import 'bootstrap/dist/css/bootstrap.min.css';
import AqgSetup3 from "./components/AqgSetup3";
import './App.css';
import { useAuth0 } from './react-auth0-spa'
import Banjo from './BackgroundImgs/Banjo.jpg'
import Hands from './BackgroundImgs/Hands.jpg'
import Mic from './BackgroundImgs/Mic.jpg'
import Sax from './BackgroundImgs/Sax.jpg'
import { Button } from 'reactstrap'

function App() {
  const { user } = useAuth0()
  const [bgImgArray] = useState([Banjo, Hands, Mic, Sax])
  const [ bgImg, setBgImg ] = useState(Banjo)
  const { loginWithRedirect, isAuthenticated } = useAuth0();

  useEffect(() => {
    bgTransition()
  }, [] )

  const bgTransition = () => {
    let newNum = Math.floor(Math.random() * 4)
    setBgImg(bgImgArray[newNum])
    setTimeout(() => {
      bgTransition()
    }, 5000)
  }

  if(!bgImgArray){
    return <div>loading...</div>
  }

  return (
    <div className="App h-100" style={{
      paddingTop: user ? '85px' : '0px'
    }}>
      <Router history={history}>
        <header>
          <NavBarA color={ user ? 'light' : ''} className={user ? 'navbar text-dark fixed-top shadow-lg' : "navbar text-light fixed-top"}/>
        </header>
        <Switch>
          <Route path="/" exact >
            <div className='homePage h-100' style={{
              display: !isAuthenticated ? 'block' : 'none',
              backgroundImage: `url(${bgImg})`,
              backgroundRepeat: 'no-repeat',
              backgroundSize: 'cover',
              webkitTransition: 'background-image 1s ease-in-out',
              transition: 'background-image 1s ease-in-out',
            }}>
              <div className='h-100 w-100 position-absolute'style={{
                background: 'linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) )',
                zIndex: '10'
              }}/>
              <div className="d-flex flex-column w-100 h-100 align-items-center justify-content-center position-relative" style={{zIndex: '100'}}>
              <h1 className='text-light'>On Demand</h1>
                <h1 className='text-light'>On DeBand</h1>
                <h6 className='text-light'>Find, Support, and Book Local Bands</h6>
                <div className='d-flex flex-row'>
                  <Button outline color='light' size='lg' className='mx-2 my-2' onClick={() => {loginWithRedirect()}}>Find Bands</Button>
                </div>
              </div>
              <div>

              </div>

            </div>

            <div style={{
              display: user ? 'block' : 'none',
            }}>
              <BookABand2 />
            </div>
          </Route>
          <PrivateRoute path="/BookABand2" component={BookABand2} />
          <PrivateRoute path="/AqgSetup3/:id" component={AqgSetup3} />
          <PrivateRoute path="/band/:id" component={LiveProfile} />
          <PrivateRoute path="/account" component={Account} />
        </Switch>
      </Router>
    </div>
  );
}

export default App;

Thanks for your help!


回答1:


You can do it with just html, with only small tweaks to your React code.

To download the image earlier you can follow this answer. The only problem is, that you don't know the url of the image, because it's randomized once you build the website.

To mitigate this, move your images out of the src folder to the public folder. I assume you would use /public/images/ to store them. Here is the modified code:

index.html

<head>
..
..
<link rel="preload" href="%PUBLIC_URL%/images/Banjo.jpg" as="image">
<link rel="preload" href="%PUBLIC_URL%/images/Hands.jpg" as="image">
<link rel="preload" href="%PUBLIC_URL%/images/Mic.jpg" as="image">
<link rel="preload" href="%PUBLIC_URL%/images/Sax.jpg" as="image">
...
</head>

App.js

import React, { useState, useEffect } from "react";
import NavBarA from "./components/NavBarA";
import { Router, Route, Switch } from "react-router-dom";
import BookABand2 from "./components/Profile/BookABand2";
import LiveProfile from './components/BookABand/LiveProfile'
import Account from './components/Account/Account'
import history from "./uitls/history";
import PrivateRoute from "./components/PrivateRoute";
import 'bootstrap/dist/css/bootstrap.min.css';
import AqgSetup3 from "./components/AqgSetup3";
import './App.css';
import { useAuth0 } from './react-auth0-spa'
import { Button } from 'reactstrap'

function App() {
  const [bgImgArray] = useState(['Banjo.jpg', 'Hands.jpg', 'Mic.jpg', 'Sax.jpg'])
  ...
  return (
    <div className="App h-100" style={{
      paddingTop: user ? '85px' : '0px'
    }}>
      <Router history={history}>
        ...
        <Switch>
          <Route path="/" exact >
            <div className='homePage h-100' style={{
              display: !isAuthenticated ? 'block' : 'none',
              backgroundImage: `url(/public/images/${bgImg})`,
              backgroundRepeat: 'no-repeat',
              backgroundSize: 'cover',
              webkitTransition: 'background-image 1s ease-in-out',
              transition: 'background-image 1s ease-in-out',
            }}>
              ...
            </div>
          </Route>
          ...
        </Switch>
      </Router>
    </div>
  );
}

export default App;


来源:https://stackoverflow.com/questions/61576115/background-image-flickering-when-change-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!