【问题标题】: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 未定义的错误。

标签: javascript html reactjs camera


【解决方案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;
    

    【讨论】:

      猜你喜欢
      • 2020-08-26
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      相关资源
      最近更新 更多