将类组件转换为功能组件

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;

【讨论】:

以上是关于将类组件转换为功能组件的主要内容,如果未能解决你的问题,请参考以下文章

将类组件转换为功能组件

将类组件转换为功能组件后的问题[重复]

React将类组件转换为功能组件不起作用

将类组件转换为功能组件 TypeError: users.filter is not a function

将类重构为 React 中的功能组件

使用钩子将类组件转换为函数式