简体   繁体   English

与 useEffect 一起使用时,React Hook useRef 为 null

[英]React Hook useRef is null when used with useEffect

I'd like to use React Hook's useRef to set the src object of a video stream but the video ref null and I get the error: TypeError: Cannot set property 'srcObject' of null at getMedia . I'd like to use React Hook's useRef to set the src object of a video stream but the video ref null and I get the error: TypeError: Cannot set property 'srcObject' of null at getMedia . I am using useEffect to call the function that logs the ref.我正在使用useEffect调用记录参考的 function。

The strange part is I see both null and a value for current.奇怪的是我看到了null和电流值。 See screenshot of console log:查看控制台日志的屏幕截图:

截屏

I have read the docs on useRef and looked at every other post on Stack Overflow and Github but cannot figure this out.我已经阅读了useRef上的文档并查看了 Stack Overflow 和 Github 上的所有其他帖子,但无法弄清楚这一点。 The closest post is this one .最接近的帖子是这个 What am I doing wrong?我究竟做错了什么?

Condensed code:精简代码:

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

Full code: Sandbox: https://codesandbox.io/s/blissful-goldstine-rp9k5完整代码:沙盒: https://codesandbox.io/s/blissful-goldstine-rp9k5

Seems to be working fine on my end based on your provided code.根据您提供的代码,我的工作似乎很好。

I added webcamRef.current.play() to the effect in order to get the video to play.我在效果中添加了webcamRef.current.play()以播放视频。

useEffect should always run after the component has fully mounted (/rendered), so webcamRef.current shouldn't be null when the effect runs unless video was conditionally rendered. useEffect 应始终在组件完全安装(/渲染)后运行,因此当效果运行时 webcamRef.current 不应为 null ,除非有条件地渲染视频。

Also, in the useEffect, you shouldn't have a ref in the dependency array as that does nothing and makes it look like the effect will get re-triggered when the ref changes even though it won't.此外,在 useEffect 中,您不应该在依赖数组中有 ref,因为它什么都不做,并且看起来效果会在 ref 更改时重新触发,即使它不会。

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


From JAM's update about conditionally rendering the video:来自 JAM 关于有条件渲染视频的更新:

The main thing you want to do is separate out the effects.您要做的主要事情是分离出效果。 You want the getMedia call to happen only when the video element is on the page, otherwise webcamRef.current can't point to anything.您希望 getMedia 调用在视频元素在页面上时发生,否则webcamRef.current不能指向任何内容。

So, in this case, I made the first effect set loaded to true, then I made a second effect that used loaded as a dependency so that getMedia can be called once the pre-processing finishes.因此,在这种情况下,我将第一个效果集加载为 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/distracted-violet-s92d0?file=/src/App.js https://codesandbox.io/s/distracted-violet-s92d0?file=/src/App.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM