1

I am building a portfolio website and would like to implement a loading screen before each and every page get loaded or rendered in the browser. In my portfolio I have implemented a theme switcher( between light/dark) using react context api. I have tried to integrate a loading screen using this stack overflow thread as reference. But I couldn't find a way around from these solution to incorporate the current theme in to the loading component. I have tried building a custom loading screen and incorporate the theme in to it but for it requires the entire DOM of the home screen to be loaded and also tried using the useEffect hook, so that solution didn't work. Please Help me solve the issue or suggest a way around. Thank you!

Currently I have implemented it using a simple query selector to update the class of a div in index.html file(within the React app's public folder) dynamically. The code is provided bellow.

index.html

<!DOCTYPE html>
<html lang="en">

  <head>
    <style>
      .svgLoader {
        animation: spin 4s linear infinite;
        margin: auto;
      }

      .divLoader {
        width: 100vw;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 9999;
      }

      .dark {
        background-color: #0d1117;
      }

      .light {
        background-color: white;
      }

      @keyframes spin {
        0% {
          transform: rotate(0deg);
        }

        100% {
          transform: rotate(360deg);
        }
      }
    </style>

  </head>

  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root">
      <!--loading screen-->
      <div id="loader" class="divLoader">
        <svg class="svgLoader" viewBox="0 0 100 100" width="10em" height="10em">
          <path ng-attr-d="{{config.pathCmd}}" ng-attr-fill="{{config.color}}" stroke="none"
            d="M10 50A40 40 0 0 0 90 50A40 42 0 0 1 10 50" fill="#515390" transform="rotate(179.719 50 51)">
            <animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 51;360 50 51"
              keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
          </path>
        </svg>
      </div>
    </div>
  </body>

  <script>
    function setLoadTheme() {
      const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
      const theme = darkMediaQuery.matches ? 'dark' : 'light';
      document.getElementById('loader').className = `divLoader ${theme}`;
    }
    setLoadTheme();
  </script>

</html>

I have take the code for the loader animation for here. actually this method worked with the help of custom script for getting the current theme from the browser defaults. But the issue comes when the actual user is toggling between the themes when they are interacting with the website. When the user toggle it manually I am not able to incorporate that change in to the loading screen's theme, since it is hard coded in the index.html file. I am also sharing the context that I have created for toggling between the themes in my web app.

Theme.js

import { createContext, useEffect, useState } from 'react'
import PropTypes from 'prop-types'

const ThemeContext = createContext()

function ThemeProvider({ children }) {
  const [themeName, setThemeName] = useState('light')

  useEffect(() => {
    const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
    setThemeName(darkMediaQuery.matches ? 'dark' : 'light')
    darkMediaQuery.addEventListener('change', (e) => {
      setThemeName(e.matches ? 'dark' : 'light')
    })
  }, [])

  const toggleTheme = () => {
    const name = themeName === 'dark' ? 'light' : 'dark'
    localStorage.setItem('themeName', name)
    setThemeName(name)
  }

  return (
    // eslint-disable-next-line react/jsx-no-constructed-context-values
    <ThemeContext.Provider value={[{ themeName, toggleTheme }]}>
      {children}
    </ThemeContext.Provider>
  )
}

ThemeProvider.propTypes = {
  children: PropTypes.node.isRequired,
}

export { ThemeProvider, ThemeContext }

Jishnu
  • 151
  • 1
  • 2
  • 12
  • Pls provide some code with explaination. – Abhishek Gurjar Dec 27 '22 at 10:01
  • I have updated the question along with the code. Hope the problem here is clear and this way around seems to work in chrome and Firefox but I am not able render the theme based loading screen on brave browser. – Jishnu Jan 01 '23 at 17:41

0 Answers0