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 离开全屏时它会自动工作。
这解决了我遇到的特定问题。
我正在尝试创建一个简单的应用程序,该应用程序在单击按钮时进入全屏并在另一个按钮上离开全屏。
虽然我知道了,但我无法在按 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 离开全屏时它会自动工作。
这解决了我遇到的特定问题。