Reactjs 如何避免使用useRef在react中重新渲染?
我正在创建一个组件来拍照并上传到服务器。当我在输入框中键入内容时,setTitle是触发器,组件被重新渲染。当这种情况发生时,视频变黑了。如何避免视频被渲染Reactjs 如何避免使用useRef在react中重新渲染?,reactjs,video,react-hooks,Reactjs,Video,React Hooks,我正在创建一个组件来拍照并上传到服务器。当我在输入框中键入内容时,setTitle是触发器,组件被重新渲染。当这种情况发生时,视频变黑了。如何避免视频被渲染 function Camera() { console.log("Render camera"); const [title, setTitle] = useState(""); let videoRef = useRef(null); let canvasRef = useRef(); // This is a cust
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>
);
}
功能摄像机(){
控制台日志(“渲染摄影机”);
const[title,setTitle]=useState(“”);
让videoRef=useRef(null);
让canvasRef=useRef();
//这是一个用于获取相机输入的自定义挂钩
const mediaStream=useUserMedia({
音频:错,
视频:{宽度:300,高度:300}
});
if(mediaStream&&videoRef.current&&videoRef.current.srcObject){
videoRef.current.srcObject=mediaStream;
}
//卸载组件时停止视频流
useffect(()=>{
return()=>{
if(媒体流){
mediaStream.getTracks()[0]。停止();
}
};
},[mediaStream]);
const handlePostTitle=e=>{
e、 预防默认值();
设置标题(如目标值);
};
const onCapture=async blob=>{
日志(“上传到服务器”);
};
返回(
{
如果(canvasRef){
const context=canvasRef.current.getContext(“2d”);
//这是用来旋转照片的
语境翻译(300,0);
背景量表(-1,1);
drawImage(videoRef.current,0,0,300,300);
canvasRef.current.toBlob(blob=>onCapture(blob),“image/jpeg”,1);
clearRect(0,03000);
}
}}
>
拍照
);
}
完整代码可在上找到,请尝试此代码,
代码沙盒链接-
import React,{useState,useRef,useffect}来自“React”;
从“react dom”导入react dom;
从“/hooks/use user media”导入{useUserMedia}”;
功能摄像机(){
控制台日志(“渲染摄影机”);
让videoRef=useRef(null);
让canvasRef=useRef();
const mediaStream=useUserMedia({
音频:错,
视频:{宽度:300,高度:300}
});
if(mediaStream&&videoRef.current&&videoRef.current.srcObject){
videoRef.current.srcObject=mediaStream;
}
//卸载组件时停止视频流
useffect(()=>{
return()=>{
if(媒体流){
mediaStream.getTracks()[0]。停止();
}
};
},[mediaStream]);
const onCapture=async blob=>{
日志(“上传到服务器”);
};
设titleRef=useRef();
const OnSubmit=()=>{
日志(“title”,titleRef.current.value);
};
返回(
{
OnSubmit();
如果(canvasRef){
const context=canvasRef.current.getContext(“2d”);
//这是用来旋转照片的
语境翻译(300,0);
背景量表(-1,1);
drawImage(videoRef.current,0,0,300,300);
canvasRef.current.toBlob(blob=>onCapture(blob),“image/jpeg”,1);
clearRect(0,03000);
}
}}
>
拍照
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);
请使用我们的代码格式将您的问题包括在代码中,而不是发布代码的外部链接。有关更多信息,请参阅以及如何包含。非常感谢,这很有用。据我所知,访问输入元素的解决方案是使用useRef,而不是“传统的表单方法”
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);