当前位置: 首页 > 知识库问答 >
问题:

与useEffect一起使用时,React钩子useRef为空

长孙逸仙
2023-03-14

我想使用React钩子的usereF来设置视频流的src对象,但视频引用为null,我得到的错误是:TypeError:无法在GetMedia处设置null的属性“src对象”。我正在使用useEffect来调用记录引用的函数。

奇怪的是,我看到了null和一个current值。参见控制台日志截图:

我读过useRef的文档,也看过关于Stack Overflow和Github的所有其他文章,但无法弄清楚这一点。最近的一个帖子是这一个。我做错了什么?

精简代码:

const App = () => {
  const webcamRef = useRef(null)

  useEffect(() => {
    getMedia();
  }, [webcamRef])

  const getMedia = async () => {
    try {
      console.log(webcamRef);
      let stream = await navigator.mediaDevices.getUserMedia({ video: true });
      webcamRef.current.srcObject = stream;
    } catch (err) {
      console.error(err);
    }
  };

  return <video id='webcam' ref={webcamRef} />
}

完整代码:沙箱:https://codesandbox.io/s/blissful-goldstine-rp9k5

共有1个答案

姜德泽
2023-03-14

根据您提供的代码,在我的端似乎工作得很好。

为了播放视频,我添加了webcamref.current.play()

useEffect应该总是在组件完全挂载(/呈现)之后运行,所以当效果运行时webcamref.current不应该为null,除非有条件地呈现了视频。

此外,在useEffect中,不应该在依赖数组中有一个ref,因为这样做什么也不做,而且看起来在ref发生更改时效果会被重新触发,尽管它不会发生更改。

https://codesandbox.io/s/informing-sara-9skhr?file=/src/app.js

来自Jam关于有条件呈现视频的更新:

你要做的主要事情是分离出效果。您希望getMedia调用仅在video元素在页面上时发生,否则webcamref.current不能指向任何内容。

因此,在本例中,我将第一个效果设置为loaded为true,然后创建第二个效果,使用loaded作为依赖项,以便在预处理完成后调用getMedia。

  useEffect(() => {
    const loadItems = async () => {
      console.log("preprocessing here");
    };  
    loadItems().then(() => {
      setLoadedStatus(true);
    });
  }, []);

  useEffect(() => {
    if (!loaded) return;
    const getMedia = async () => {
      try {
        console.log(webcamRef.current);
        let stream = await navigator.mediaDevices.getUserMedia({ video: true });
        webcamRef.current.srcObject = stream;
        webcamRef.current.play();
      } catch (err) {
        console.error(err);
      }
    };

    getMedia();
  }, [loaded]);

https://codesandbox.io/s/discarted-violet-S92D0?file=/src/app.js

 类似资料:
  • 有人能解释一下我做错了什么吗?我有一个react功能组件,在其中我使用useEffect钩子从服务器获取一些数据,并将这些数据放入状态值。在获取数据之后,在同一个useHook中,我需要使用该状态值,但由于某些原因,该值是明确的。看看我的示例,console有一个空字符串,但在浏览器上我可以看到该值。 链接到codesandbox。

  • 我在useeffect钩子上得到以下错误。 React Hook use效应有一个缺失的依赖项:当前页面。要么包含它,要么删除依赖array.eslintreact-钩子/穷举-deps 你知道我为什么会得到这个吗? }

  • 我试图创建一个简单的组件,从Apollo GraphQL服务器(查询)返回我的所有组织。我想从一个上下文状态呈现所有这些组织,在这个上下文状态下,在组件挂载(由useEffect挂钩处理)之后,可以使用分派方法放置这些组织。 如果状态结果(organizations数组)为空,useEffect钩子应该调用函数getOrganizations,然后调用自定义钩子useGetOrganization

  • 如何使用钩子(或任何其他钩子)来复制? 在传统的类组件中,我将执行以下操作: 使用hook: (完整示例:https://codesandbox.io/s/2oo7zqzx1n) 这不起作用,因为在中返回的“cleanup”函数捕获装载期间的道具,而不是卸载期间的道具状态。 如何在不运行函数体(或清除)的情况下对每个道具更改进行清理? 一个类似的问题并没有涉及获得最新道具的部分。 文件状态为: 如

  • 问题内容: 我已经通过了React v16.7.0中引入的钩子。 https://reactjs.org/docs/hooks-intro.html 因此,我对钩子的理解是,我们可以在功能组件中使用状态,而无需在react中编写类组件。这真是一个了不起的功能。 但是我对在功能组件中使用钩子一无所知。 如果使用钩子,如何在上述功能组件中使用生命周期方法? 问题答案: 以下是最常见生命周期的示例: 传

  • 问题内容: 我试图了解用React的钩子代替钩子的用例是什么。 它们似乎都充当其输入的状态更改的侦听器(示例取自React Docs): 但是,该钩子还具有清理资源的额外好处,而您以前可能会使用。 那么,有什么好的用例呢?而且,我在这里想念什么? 问题答案: 与之相关的时序非常具体,您可以在此处阅读。指定的功能将在渲染完成且DOM已更新后执行。这将在每次渲染后发生,其中第二参数数组中指定的任何值都