JodusNodus / react-qr-reader

React component for reading QR codes from webcam.
https://jodusnodus.github.io/react-qr-reader
MIT License
1.13k stars 406 forks source link

Type Error in React Typescript project #233

Open vikingsurfeur opened 2 years ago

vikingsurfeur commented 2 years ago

Hi there ! I am working on a React Typescript project and was able to install the latest version of react-qr-reader to scan my QR Code. I end up with the error below and a multitude of event errors if I log the errors on the {data} captures.

My Component :

import { FC, useState, useEffect } from "react";

import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../store";

import { getAccessories } from "../redux/actions/accessoriesAction";
import { getCheckpoints } from "../redux/actions/checkpointsActions";
import { getMaterialsByMaterialReference } from "../redux/actions/materialAction";
import { getMaintenancesByMaterialId } from "../redux/actions/maintenancesAction";
import { getRentalsInterventionsByRentalId } from "../redux/actions/interventionsAction";

import { QrReader } from "react-qr-reader";
import { Formik, Form, Field } from "formik";

import { searchReferenceSchema } from "../validation/scan.schema";
import { INIT_VALUES_SEARCH_REFERENCE } from "../constants/initial.values.searchReference";

import { IMaterialState } from "../interfaces/material/IMaterialState";
import { IRentalState } from "../interfaces/rental/IRentalState";
import { IUserState } from "../interfaces/user/IUserState";
import { ISearchReference } from "../interfaces/material.search/ISearchReference";

import NavbarTitle from "../components/Navbar.title";
import ModalEmptyMaterials from "../components/Modal.empty.materials";
import ModalNetworkState from "../components/Modal.network.state";

import ScanLayout from "../assets/styles/styled/Scan.layout";
import Logo from "../assets/styles/styled/Logo";
import { Button } from "react-bootstrap";
import logo from "../assets/img/logo.png";
import { getLastRentalInterventionByMaterialId } from "../redux/actions/rentalAction";

const Scan: FC = () => {
  // Handle User Data
  const userConnected = useSelector<RootState, IUserState>(
    (state) => state.userLogin
  );
  const { userData } = userConnected;

  // Handle QR Code
  const [data, setData] = useState<ISearchReference | string>("Scannez votre QR Code");
  const [isValidData, setIsValidData] = useState(false);

  // Handle Retrieve APIs Data
  const [isSearching, setIsSearching] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const dispatch = useDispatch();

  const materialsState = useSelector<RootState, IMaterialState>((state) => state.material);
  const { loading, material } = materialsState;

  const rentalState = useSelector<RootState, IRentalState>((state) => state.rental);
  const { rental } = rentalState;

  useEffect(() => {
    loading ? setIsLoading(true) : setIsLoading(false);
  }, [loading]);

  useEffect(() => {
    if (isValidData) {
      data && dispatch(getMaterialsByMaterialReference(data));
      setIsSearching(true);
    }
  }, [isValidData, data, dispatch]);

  useEffect(() => {
    if (material?.id) {
      dispatch(getAccessories());
      dispatch(getCheckpoints());
      dispatch(getMaintenancesByMaterialId(material.id));
      dispatch(getLastRentalInterventionByMaterialId(material.id));
    }
  }, [material, dispatch]);

  useEffect(() => {
    rental?.id && dispatch(getRentalsInterventionsByRentalId(rental.id));
  }, [rental, dispatch]);

  // Handle Manual Search
  const handleSearching = ({ searchReference }: ISearchReference) => {
    dispatch(getMaterialsByMaterialReference(searchReference));
    setIsSearching(true);
  };

  return (
    <ScanLayout>
      <NavbarTitle
        title="RECHERCHE MACHINE"
        userConnected={userData?.user.email}
      />
      <QrReader
        onResult={(result, error) => {
          if (!!result) {
            setData(result?.getText());
            setIsValidData(true);
            setTimeout(() => {
              setIsValidData(false);
            }, 2000);
          }

          if (!!error) {
            console.log(error);
          }
        }}
        containerStyle={{
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          width: "240px",
          height: "180px",
          overflow: "hidden",
          border: `4px solid ${isValidData ? "green" : "red"}`,
          borderRadius: "10px",
        }}
        constraints={{
          facingMode: "environment",
        }}
        className="shadow"
      />
      <p className="mt-4">{data}</p>
      <h5 className="mt-4">Recherche Manuelle de la Machine</h5>
      <Formik
        initialValues={INIT_VALUES_SEARCH_REFERENCE}
        validationSchema={searchReferenceSchema}
        onSubmit={handleSearching}
      >
        {({ errors, touched }) => (
          <Form className="d-flex flex-column justify-content-center">
            <div className="form-group required text-center">
              <label htmlFor="searchReference" className="my-2">
                Saisissez l'identifiant de la machine
              </label>
              <div className="input-group mb-2">
                <Field
                  type="text"
                  name="searchReference"
                  className="form-control shadow-sm"
                  id="searchReference"
                  placeholder="identifiant de la machine"
                />
              </div>
              {errors.searchReference && touched.searchReference && (
                <div className="text-danger">{errors.searchReference}</div>
              )}
            </div>
            <Button
              className="mt-4"
              variant={isLoading ? "warning" : "primary"}
              type="submit"
              disabled={isLoading}
            >
              {isLoading ? "Recherche..." : "Rechercher"}
            </Button>
          </Form>
        )}
      </Formik>
      <Logo src={logo} alt="logo LCMI" />
      <ModalEmptyMaterials searching={isSearching} />
      <ModalNetworkState />
    </ScanLayout>
  );
};

export default Scan;

Console Error :

My package.json :

{
  "name": "lcmi_pwa",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "@types/jest": "^26.0.24",
    "@types/node": "^12.20.46",
    "@types/react": "^16.14.23",
    "@types/react-bootstrap": "^0.32.29",
    "@types/react-dom": "^16.9.14",
    "@types/react-redux": "^7.1.23",
    "@types/styled-components": "^5.1.24",
    "axios": "^0.26.0",
    "bootstrap": "^5.1.3",
    "formik": "^2.2.9",
    "react": "^17.0.2",
    "react-bootstrap": "^2.1.2",
    "react-bootstrap-icons": "^1.7.2",
    "react-dom": "^17.0.2",
    "react-qr-reader": "^3.0.0-beta-1",
    "react-redux": "^7.2.6",
    "react-router-dom": "^6.2.2",
    "react-scripts": "5.0.0",
    "redux-devtools-extension": "^2.13.9",
    "redux-persist": "^6.0.0",
    "redux-thunk": "^2.4.1",
    "signature_pad": "^4.0.2",
    "styled-components": "^5.3.3",
    "typescript": "^4.6.2",
    "web-vitals": "^0.2.4",
    "workbox-background-sync": "^5.1.4",
    "workbox-broadcast-update": "^5.1.4",
    "workbox-cacheable-response": "^5.1.4",
    "workbox-core": "^5.1.4",
    "workbox-expiration": "^5.1.4",
    "workbox-google-analytics": "^5.1.4",
    "workbox-navigation-preload": "^5.1.4",
    "workbox-precaching": "^5.1.4",
    "workbox-range-requests": "^5.1.4",
    "workbox-routing": "^5.1.4",
    "workbox-strategies": "^5.1.4",
    "workbox-streams": "^5.1.4",
    "yup": "^0.32.11"
  },
  "scripts": {
    "start": "NODE_ENV=development.local HTTPS=true react-scripts start",
    "build": "NODE_ENV=production.local react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Then I avoid these errors by giving particular parameters in the constraints parameter or others. Thank you in advance.

RomuloDevelop commented 2 years ago

Can you tell what parameters to add? I'm having the same issue...

xjdesigns commented 2 years ago

@vikingsurfeur @RomuloDevelop From what I can tell is doing the install is adding the beta version which appears to have issues. I ran into the same thing. I am currently working through checking the last published version of 2.2.1.

If you go npm and click on the versions tab, then select that version it will load the README for that and docs. I have not finished trying to handle it but so far I didnt see the same issues.

Hopefully the developer can address what the problem is. It seems that when the error occurs its not handling cleaning up the mediaUser and I was stuck in a loop which would go infinite if I did not kill development.