将类组件转换为功能组件
Posted
技术标签:
【中文标题】将类组件转换为功能组件【英文标题】:Convert Class Component to Functional Component 【发布时间】:2020-02-08 11:13:33 【问题描述】:我会尝试解释任务,然后告诉你我的问题。我的任务是添加一个可以拍照的网络摄像头组件,然后单击按钮上传图片。
我正在使用 react-webcam 库,这个:https://www.npmjs.com/package/react-webcam
并创建了一个类组件“class UploadPhoto extends Component
”,在其中我正在渲染 react-webcam(网络摄像头标签)并能够成功显示网络摄像头。
但是,当我将以下属性 (ref=webcamRef
) 添加到标记时,我收到一个错误,指出我正在进行无效的钩子调用,因为 webcamRef 已初始化为钩子 useRef(null)。如下:
const webcamRef = React.useRef(null);
错误:
未捕获的不变违规:无效的挂钩调用。钩子只能是 在函数组件的主体内部调用。
我知道我们不能在类组件中调用钩子,所以我的问题是如何将我的类组件转换为功能组件,以便我可以使用这个钩子,这将有助于我拍摄照片。
如果您需要我提供更多信息,请告诉我。
谢谢。 PS - 我对 ReactJS 还很陌生,正在尝试学习它。
以下是我的 UploadPhoto 类组件:
import React, Fragment, useRef, Component from 'react';
import ReactDOM from 'react-dom';
import Camera from '../../lib';
import Header from '../header';
import Webcam from "react-webcam";
import
Button,
from 'reactstrap';
import axios from "axios/index";
class UploadPhoto extends Component
constructor(props)
super(props);
this.capture = this.capture.bind(this)
this.next = this.next.bind(this)
capture(imgSrc)
console.log("image captured : " + imgSrc);
next()
console.log("next button clicked")
//go to review details component
// this.props.history.push("/review-details");
render()
const webcamRef = React.useRef(null);
return (
<div className="text-center">
<div>
Take a Picture
</div>
<Webcam
audio=false
height=500
ref=webcamRef
screenshotFormat="image/jpeg"
width=600 >
<Button className="position-relative text-center" onClick=this.capture>Capture photo</Button>
</Webcam>
<div>
<Button className="position-relative text-center btn-start" onClick=this.next>NEXT</Button>
</div>
</div>
);
export default UploadPhoto;
【问题讨论】:
如果您想将其更改为功能组件,那很好,但它不应该是必需的,因为类组件中也支持 refs。只是useRef
是你不能使用的。您是否考虑过使用createRef
(reactjs.org/docs/refs-and-the-dom.html)?
谢谢,@NicholasTower 我已经尝试过 createRef 并解决了无效挂钩调用的错误。但是我仍在尝试找到一种方法来捕获图像并将其传递给 capture() 方法。你能帮我吗,谢谢。
const imageSrc = webcamRef.current.getScreenshot();
@jered 仅当我使用功能组件时才有效,但是如何在类组件中使用它?定义 imageSrc 后,出现 webcamRef 未定义的错误。
【参考方案1】:
虽然您可以将组件转换为功能组件,但这并不是解决此问题所必需的。 Refs 也可以在类组件中使用,只是不能使用 useRef
。相反,请使用createRef
:
constructor(props)
super(props);
this.capture = this.capture.bind(this)
this.next = this.next.bind(this)
this.webcamRef = React.createRef();
componentDidMount()
const imageSrc = this.webcamRef.current.getScreenshot();
this.capture(imagesrc);
render()
return (
<div className="text-center">
<div>
Take a Picture
</div>
<Webcam
audio=false
height=500
ref=this.webcamRef
screenshotFormat="image/jpeg"
width=600 >
<Button className="position-relative text-center" onClick=this.capture>Capture photo</Button>
</Webcam>
<div>
<Button className="position-relative text-center btn-start" onClick=this.next>NEXT</Button>
</div>
</div>
);
【讨论】:
【参考方案2】:由于问题是如何将类转换为函数组件,所以这里是与函数相同的组件:
import React, Fragment, useRef, Component from 'react';
import ReactDOM from 'react-dom';
import Camera from '../../lib';
import Header from '../header';
import Webcam from "react-webcam";
import
Button,
from 'reactstrap';
import axios from "axios/index";
const UploadPhoto = props =>
const webcamRef = useRef(null);
const capture = () =>
const imgSrc = webcamRef.current.getScreenshot();
console.log("image captured : " + imgSrc);
const next = () =>
console.log("next button clicked");
//go to review details component
// props.history.push("/review-details");
return (
<div className="text-center">
<div>
Take a Picture
</div>
<Webcam
audio=false
height=500
ref=webcamRef
screenshotFormat="image/jpeg"
width=600 >
<Button className="position-relative text-center" onClick=capture>Capture photo</Button>
</Webcam>
<div>
<Button className="position-relative text-center btn-start" onClick=next>NEXT</Button>
</div>
</div>
)
export default UploadPhoto;
【讨论】:
以上是关于将类组件转换为功能组件的主要内容,如果未能解决你的问题,请参考以下文章