与 useEffect 一起使用时,React Hook useRef 为 null
React Hook useRef is null when used with useEffect
我想使用 React Hook 的 useRef
设置视频流的 src 对象,但视频引用为空,我收到错误:TypeError: 无法设置 属性 'srcObject' 在 getMedia 处为空。我正在使用 useEffect
来调用记录 ref 的函数。
奇怪的是我同时看到了 null
和电流值。查看控制台日志的屏幕截图:
我已阅读 useRef and looked at every other post on Stack Overflow and Github but cannot figure this out. The closest post is 上的文档。我做错了什么?
压缩代码:
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} />
}
根据您提供的代码,我这边似乎工作正常。
为了让视频播放,我添加了 webcamRef.current.play()
效果。
useEffect 应始终 运行 在组件完全安装(/渲染)后,因此当效果 运行 时 webcamRef.current 不应为空,除非有条件地渲染视频。
另外,在 useEffect 中,你不应该在依赖数组中有一个 ref,因为它什么都不做,并且看起来效果会在 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
我想使用 React Hook 的 useRef
设置视频流的 src 对象,但视频引用为空,我收到错误:TypeError: 无法设置 属性 'srcObject' 在 getMedia 处为空。我正在使用 useEffect
来调用记录 ref 的函数。
奇怪的是我同时看到了 null
和电流值。查看控制台日志的屏幕截图:
我已阅读 useRef and looked at every other post on Stack Overflow and Github but cannot figure this out. The closest post is
压缩代码:
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} />
}
根据您提供的代码,我这边似乎工作正常。
为了让视频播放,我添加了 webcamRef.current.play()
效果。
useEffect 应始终 运行 在组件完全安装(/渲染)后,因此当效果 运行 时 webcamRef.current 不应为空,除非有条件地渲染视频。
另外,在 useEffect 中,你不应该在依赖数组中有一个 ref,因为它什么都不做,并且看起来效果会在 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