布局重新渲染后,如何告诉 React 在自定义 Hook 内使用 useRef?

问题描述 投票:0回答:1

所以这有点复杂。

我有一个 React 组件,客户询问我们是否可以将页面的一部分全屏显示(例如 YouTube 全屏视频)。我在组件的一角有一个小按钮,用户可以使用它来全屏切换组件的这一部分。

我遇到的问题是组件需要从另一个源提取的数据,并通过 React 内容对象传入。在页面加载之前需要这些数据。

所以我认为为此制作一个自定义钩子是有意义的。

我的钩子是这样的。

useFullScreen.tsx

import * as React from "react";

type useFullScreenProps = {
    ref: React.MutableRefObject<null | HTMLDivElement>;
};

const useFullScreen = ({ref} : useFullScreenProps) => {

    
    const [isFullScreen, setIsFullScreen] = React.useState(false);
  
    const enterFullScreen = () => {
        if (ref.current) {
            ref.current.requestFullscreen();
        }
    };

    const exitFullScreen = () => {
        if (document.fullscreenElement) {
            document.exitFullscreen();
        }
    };

    const toggleFullScreen = () => {
        isFullScreen ? exitFullScreen() : enterFullScreen();
    };

    React.useEffect(() => {
        const handleFullscreenChange = () => {
            setIsFullScreen(document.fullscreenElement !== null);
        };

        document.addEventListener("fullscreenchange", handleFullscreenChange);

        return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
    }, []);


    return [isFullScreen, toggleFullScreen];

};

export default useFullScreen;

查看器组件这样调用它。

ViewerComponent.tsx

import useFullScreen from "./Common/useFullScreen";

const ViewerComponent = () => {
    let viewerRef = React.useRef<HTMLDivElement>(null);
    const [isFullScreen, toggleFullScreen] = useFullScreen(viewerRef as any);
    const viewData = useClientObject<ExamData>(React.useContext(ClientContext), "viewer_data");


    if (viewData === undefined || Object.keys(viewData).length === 0) {
        return <h4> Loading page</h4>
    }

 return (

   <div id="view-workspace" ref={viewerRef}>

     <button onClick={toggleFullScreen as () => void}>
      {isFullScreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}
     </button> 

     <div> {/* Rest of the page goes here */} </div>

   <div>
)

};

所以问题是我不知道如何将 ref 传递给 hook 以便它可以使用它。

因为我的页面在渲染整个组件之前使用了它所需的数据。它永远看不到

viewerRef
DOM 元素。

我已经尝试了所有方法,使用useEffect我可以正确获取对dom元素的引用,但是我不知道如何再次调用该钩子?

React.useEffect(()=>{
 console.log(viewerRef.current) <-- this works, but now how do I tell the hook about it
},
[examData])

reactjs typescript react-hooks
1个回答
0
投票

建议: 传递给

{ ref: viewerRef }
时使用
useFullScreen
作为参数。

这是修改后的代码:

const [isFullScreen, toggleFullScreen] = useFullScreen({ ref: viewerRef });

这里的主要变化是无论数据是否已完成加载,都将

div
指向的
viewerRef
(即
<div id="view-workspace" ref={viewerRef}>
)保留在 DOM 中。这样,即使在初始渲染期间尚未加载数据,
viewerRef.current
仍然可以指向这个
div
元素。

不建议先将

viewerRef
转换为
any
,然后再将其传递给
useFullScreen

强制转换为

any
会削弱类型检查,可能会导致传递错误参数时无法及时检测到错误。

例如,如果

useFullScreen
需要一个对象作为参数,但使用
any
绕过类型检查,TypeScript 将不会抛出错误。

如果以后

useFullScreen
需要更多的参数,这种直接传递的方式也不容易扩展。

© www.soinside.com 2019 - 2024. All rights reserved.