我正在创建一个组件来拍照并上传到服务器。当我在输入框中键入内容时,setTitle 是触发器,组件会重新渲染。发生这种情况时,视频变黑。如何避免渲染视频?
function Camera() {
console.log("Render camera");
const [title, setTitle] = useState("");
let videoRef = useRef(null);
let canvasRef = useRef();
// This is a custom hook for get the camera input
const mediaStream = useUserMedia({
audio: false,
video: { width: 300, height: 300 }
});
if (mediaStream && videoRef.current && !videoRef.current.srcObject) {
videoRef.current.srcObject = mediaStream;
}
// Stop the video stream when component is unmount
useEffect(() => {
return () => {
if (mediaStream) {
mediaStream.getTracks()[0].stop();
}
};
}, [mediaStream]);
const handlePostTitle = e => {
e.preventDefault();
setTitle(e.target.value);
};
const onCapture = async blob => {
console.log("Upload to server");
};
return (
<form>
<div>
<video ref={videoRef} autoPlay muted />
<canvas ref={canvasRef} width={300} height={300} />
</div>
<div>
<input
type="text"
name="title"
value={title}
onChange={handlePostTitle}
placeholder="Title"
/>
</div>
<button
type="submit"
onClick={() => {
if (canvasRef) {
const context = canvasRef.current.getContext("2d");
// This is for rotate the photo
context.translate(300, 0);
context.scale(-1, 1);
context.drawImage(videoRef.current, 0, 0, 300, 300);
canvasRef.current.toBlob(blob => onCapture(blob), "image/jpeg", 1);
context.clearRect(0, 0, 300, 300);
}
}}
>
Take photo
</button>
</form>
);
}
完整的代码可在 https://codesandbox.io/s/react-camera-component-with-hooks-s6pmb
试试这段代码, 代码沙盒链接 - https://codesandbox.io/s/react-camera-component-with-hooks-n9ey9
import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";
import { useUserMedia } from "./hooks/use-user-media";
function Camera() {
console.log("Render camera");
let videoRef = useRef(null);
let canvasRef = useRef();
const mediaStream = useUserMedia({
audio: false,
video: { width: 300, height: 300 }
});
if (mediaStream && videoRef.current && !videoRef.current.srcObject) {
videoRef.current.srcObject = mediaStream;
}
// Stop the video stream when component is unmount
useEffect(() => {
return () => {
if (mediaStream) {
mediaStream.getTracks()[0].stop();
}
};
}, [mediaStream]);
const onCapture = async blob => {
console.log("Upload to server");
};
let titleRef = useRef();
const OnSubmit = () => {
console.log("title", titleRef.current.value);
};
return (
<form>
<div>
<video ref={videoRef} autoPlay muted />
<canvas ref={canvasRef} width={300} height={300} />
</div>
<div>
<input type="text" name="title" placeholder="Title" ref={titleRef} />
</div>
<button
type="submit"
onClick={() => {
OnSubmit();
if (canvasRef) {
const context = canvasRef.current.getContext("2d");
// This is for rotate the photo
context.translate(300, 0);
context.scale(-1, 1);
context.drawImage(videoRef.current, 0, 0, 300, 300);
canvasRef.current.toBlob(blob => onCapture(blob), "image/jpeg", 1);
context.clearRect(0, 0, 300, 300);
}
}}
>
Take photo
</button>
</form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Camera />, rootElement);