React + Hooks:在全屏模式下按 ESC 键更改状态?

React + Hooks: Change State on ESC Press while in Fullscreen?

我正在尝试创建一个简单的应用程序,该应用程序在单击按钮时进入全屏并在另一个按钮上离开全屏

虽然我知道了,但我无法在按 ESC 离开全屏时更新状态。

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>
  )
}

我使用通过 Google 找到的一些东西来玩弄它,但它们只在不在全屏模式下时有效。

如果能弄明白那就太好了。

奖励:enter/exit 全屏的更好方法 :)

我将您的代码片段翻译成代码沙箱(对于以后的 SO 帖子,这很有帮助!)并添加了这个缺失的 useEffect() 实例,似乎已经满足了您的需求。可用 here.

简而言之,需要声明以下内容:

  const escapeHandler = (e) => {
    if (e.key === "Escape") {
      closeFullscreen();
    }
  };

  useEffect(() => {
    document.addEventListener("keydown", escapeHandler, false);
    return () => {
      document.removeEventListener("keydown", escapeHandler, false);
    };
  }, []);

如我在上面的评论中所述,该挂钩在初始呈现时将 keydown 侦听器添加到文档中。该侦听器将保留在文档中,直到该组件卸载并执行挂钩的 clean-up 阶段(执行返回的匿名函数)。

有关密钥的更多信息,请参阅 here for more information on useEffect() clean-up and here

我做了一些研究,我想我找到了一种更优雅的处理方式,利用 react-full-screen npm 包。

我的实现方式:

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>
  )
}

这会自动检查应用程序是否使用 reportChange 功能全屏,然后分别将 isFullscreen 的状态设置为 true 或 false。

因为它是 onChange,所以在按 ESC 离开全屏时它会自动工作。

这解决了我遇到的特定问题。