gpt4 book ai didi

react : useRef current getting null

转载 作者:行者123 更新时间:2023-12-02 01:51:46 24 4
gpt4 key购买 nike

我试图在组件得到卸载时关闭相机和手电筒,我正在使用 react 钩子(Hook)我有两个函数startCamera()和stopCamera() ,我在组件安装时调用 startcamera,在组件卸载时调用停止相机。但是在卸载时调用 stopCamera 时它向我显示错误 enter image description here

我创建了另一个按钮来测试 StopCamera() 是否正常工作,我发现它正常工作但我想在组件卸载时调用该函数

我的代码:

CameraScreen.js


import "./styles.css";
import { useState, useEffect, useRef } from "react";

export default function CameraScreen() {
const videoElement = useRef(null);
const [facingMode, setFacingMode] = useState("environment");
const handleFacingModeToggle = () => {
stopCamera();
facingMode === "environment"
? setFacingMode("user")
: setFacingMode("environment");
};
useEffect(() => {
// const getUserMedia = async () => {
// try {
// const stream = await navigator.mediaDevices.getUserMedia({
// video: true
// });
// videoElement.current.srcObject = stream;
// } catch (err) {
// console.log(err);
// }
// };
// getUserMedia();
startCamera();
return function cleanup() {
stopCamera();
};
}, []);

const stopCamera = () =>
videoElement.current.srcObject &&
videoElement.current.srcObject.getTracks().forEach((t) => t.stop());
function startCamera() {
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices
.getUserMedia({
video: { facingMode: facingMode },
width: { ideal: 1280 },
height: { ideal: 720 }
})
.then(function (stream) {
if (videoElement.current) videoElement.current.srcObject = stream;
const track = stream.getVideoTracks()[0];

//Create image capture object and get camera capabilities
const imageCapture = new ImageCapture(track);
const photoCapabilities = imageCapture
.getPhotoCapabilities()
.then(() => {
//todo: check if camera has a torch

//let there be light!

track.applyConstraints({
advanced: [{ torch: true }]
});
});
})
.catch(function (error) {
alert("Please check your device permissions");
console.log("Something went wrong!");
console.log(error);
});
if (videoElement.current)
videoElement.current.onloadeddata = function () {
if (window.NativeDevice)
window.NativeDevice.htmlCameraReadyToRecord(true);
};
}
}
return (
<>
<video
autoPlay={true}
ref={videoElement}
style={{
minHeight: "67.82vh",
maxHeight: "67.82vh",
maxWidth: "100%",
minWidth: "100%"
}}
className="border-3rem bg-[#666]"
></video>

<button onClick={stopCamera}> stopCamera</button>
</>
);
}

App.js

import "./styles.css";
import { useState } from "react";
import CameraScreen from "./cameraScreen";
export default function App() {
const [switchS, setSwitchS] = useState(false);
return (
<div>
<button className="" onClick={() => setSwitchS(!switchS)} value="switch">
switch
</button>

{switchS && <CameraScreen />}
{!switchS && "Blank Screen"}
</div>
);
}

PS:以上代码工作于:https://5t2to.csb.app/

codesandbox 链接:https://codesandbox.io/s/practical-fast-5t2to?file=/src/cameraScreen.js

最佳答案

您可以使用 useLayoutEffect 钩子(Hook)。它在卸载之前工作,如 componentWillUnmount

举个例子 https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/random.js

你可以去https://ikqdn.csb.app/randsandbox browser 中检查 console 单击 to home 按钮。

您可以看到 useEffectuseLayoutEffectunmounting 时的工作差异


它保留了 ref.current,所以你可以做的是,你可以在你正在调用的函数中传递 ref.current 就在卸载之前,以防止 ref到 dom 元素

关于 react : useRef current getting null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70181906/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com