reactjsfullscreen

Change State on ESC Press while in Fullscreen?


I am trying to create a simple app that goes into Fullscreen on Button Click and leaves Fullscreen on another.

While I have that figured out, I am not able to update the state when I'm pressing ESC to leave the Fullscreen.

import { useState } from "react"

export default function Home() {
  const [isFullscreen, setFullscreen] = useState(false)

  const makeFullscreen = () => {
    setFullscreen(true)
    document.documentElement.requestFullscreen()
  }

  const closeFullscreen = () => {
    setFullscreen(false)
    document.exitFullscreen()
  }

  console.log(isFullscreen)
  return (
    <div
      className={`flex flex-col items-center justify-center w-full h-screen ${
        isFullscreen ? "bg-black" : ""
      }`}
    >
      <div
        className={`w-5/6 space-y-6 text-center wrapper ${
          isFullscreen ? "hidden" : "visible"
        }`}
      >
        <button
          onClick={makeFullscreen}
          className={`btn btn-primary ${!isFullscreen ? "visible" : "hidden"}`}
        >
          START TEST
        </button>
      </div>
      <button
        onClick={closeFullscreen}
        className={`btn btn-accent ${isFullscreen ? "visible" : "hidden"}`}
      >
        STOP TEST
      </button>
    </div>
  )
}

I played around with it using a few things I've found via Google, but they only work as long as it's not in Fullscreen.

Would be great to figure that out.

Bonus: A better way to enter/exit fullscreen :)


Solution

  • I did a bit of research and I think I found a more elegant way of handling this, utilizing the react-full-screen npm package.

    The way I implemented it:

    import { useState, useCallback } from "react"
    import { FullScreen, useFullScreenHandle } from "react-full-screen"
    
    export default function Home() {
      const handle = useFullScreenHandle()
      const [isFullscreen, setFullscreen] = useState(false)
    
      const reportChange = useCallback((state) => {
        console.log(state)
        if (state === true) {
          setFullscreen(true)
        } else if (state === false) {
          setFullscreen(false)
        }
      })
    
      return (
        <div
          className={`flex flex-col items-center justify-center w-full h-screen ${
            isFullscreen ? "bg-black" : ""
          }`}
        >
          <div className={`w-5/6 space-y-6 text-center md:w-3/6 xl:w-2/6`}>
            <button
              onClick={(e) => {
                handle.enter()
                setFullscreen(true)
              }}
              className={`btn btn-primary ${!isFullscreen ? "visible" : "hidden"}`}
            >
              
              START TEST
            </button>
    
           
          <FullScreen
            onChange={reportChange}
            className={`${
              isFullscreen
                ? "flex flex-col items-center justify-center w-full h-screen"
                : ""
            }`}
            handle={handle}
          >
            <button
              onClick={() => {
                handle.exit()
                setFullscreen(false)
              }}
              className={`btn btn-info ${!isFullscreen ? "hidden" : "visible"}`}
            >
              STOP TEST
            </button>
          </FullScreen>
        </div>
      )
    }
    

    This automatically checks if the App is in fullscreen with the reportChange function and then sets the state of isFullscreen to true or false respectively.

    Since it's onChange, it works automatically when leaving fullscreen with a press of ESC.

    This solves the particular problem I had.