React Hook useRef имеет значение null при использовании с useEffect - PullRequest
0 голосов
/ 27 мая 2020

Я хотел бы использовать React Hook useRef для установки объекта sr c видеопотока, но ссылка на видео имеет значение null, и я получаю сообщение об ошибке: TypeError: не удается установить свойство srcObject на значение null в getMedia . Я использую useEffect для вызова функции, регистрирующей исх.

Странно то, что я вижу и null, и значение тока. См. Снимок экрана журнала консоли:

screenshot

Я прочитал документы на useRef и просмотрел все остальные сообщения о переполнении стека и 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} />
}

Полный код: Sandbox: https://codesandbox.io/s/blissful-goldstine-rp9k5

1 Ответ

0 голосов
/ 27 мая 2020

Кажется, с моей стороны все работает на основе предоставленного вами кода.

Я добавил webcamRef.current.play() к эффекту, чтобы воспроизвести видео.

useEffect всегда должен работать после того, как компонент полностью смонтирован (/ rendered), поэтому webcamRef.current не должен иметь значение null при запуске эффекта, если только видео не было условно визуализировано.

Кроме того, в useEffect вы не должны иметь ссылку массив зависимостей, поскольку он ничего не делает и создает впечатление, что эффект будет повторно запущен при изменении ref, даже если это не произойдет.

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


Из обновления JAM об условном рендеринге видео:

Главное, что вы хотите сделать, - это разделить эффекты. Вы хотите, чтобы вызов getMedia происходил только , когда элемент видео находится на странице, иначе webcamRef.current не может ни на что указывать.

Итак, в этом случае я сделал первый набор эффектов загружен в значение 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...