【问题标题】:React + Hooks: Change State on ESC Press while in Fullscreen?React + Hooks:在全屏时按 ESC 更改状态?
【发布时间】:2022-01-27 20:53:38
【问题描述】:

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

虽然我已经弄清楚了,但当我按 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 找到的东西来玩弄它,但它们只有在它不是全屏模式时才有效。

如果能解决这个问题会很棒。

奖励:进入/退出全屏的更好方法 :)

【问题讨论】:

  • 您是否尝试过在初始渲染时创建击键侦听器? This post 可能有用。唯一的区别是对于您的功能组件,您将编写一个带有空依赖数组的 useEffect() 实例,该数组声明侦听器并返回一个单独的匿名函数来删除该侦听器。
  • 您能否详细说明在这种特殊情况下您将如何做到这一点?

标签: reactjs fullscreen


【解决方案1】:

我将您的代码 sn-p 翻译成代码沙箱(对于未来的 SO 帖子,这很有帮助!)并添加了这个缺少的 useEffect() 实例,似乎已经满足了您的需求。它是可用的here

简而言之,声明了以下需求:

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

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

正如我在上面的评论中所指出的,该挂钩是在初始渲染时将 keydown 侦听器添加到文档中。该侦听器将保留在文档上,直到该组件卸载并执行挂钩的清理阶段(执行返回的匿名函数)。

有关useEffect() 清理的更多信息,请参阅here,有关密钥的更多信息,请参阅here

【讨论】:

  • 太棒了!感谢您的解释!同时我找到了解决方案,见下文!很高兴知道它是如何工作的。
【解决方案2】:

我做了一些研究,我想我找到了一种更优雅的方法来处理这个问题,使用 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会自动工作。

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

【讨论】:

    猜你喜欢
    • 2021-06-16
    • 2021-02-09
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2023-03-16
    • 2022-12-12
    • 1970-01-01
    • 2013-05-18
    相关资源
    最近更新 更多