简体   繁体   English

如何修复错误无效的挂钩调用反应本机

[英]How to fix error invalid hook call react native

How can I fix this error in react native:如何修复本机反应中的此错误:

Error: Invalid hook call.错误:无效挂钩调用。 Hooks can only be called inside of the body of a function component.钩子只能在 function 组件的内部调用。 This could happen for one of the following reasons:这可能由于以下原因之一而发生:

  1. You might have mismatching versions of React and the renderer (such as React DOM)您可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. You might be breaking the Rules of Hooks你可能违反了 Hooks 规则
  3. You might have more than one copy of React in the same app你可能在同一个应用程序中有多个 React 副本
import { cameraWithTensors } from "@tensorflow/tfjs-react-native";
import { Camera } from "expo-camera";
import { StatusBar } from "expo-status-bar";
import React, { useEffect, useState, useRef } from "react";
import {
  StyleSheet,
  Text,
  View,
  Platform,
  Dimensions,
  LogBox,
} from "react-native";
import * as cocoSsd from "@tensorflow-models/coco-ssd";
import { model } from "@tensorflow/tfjs";
import * as tf from "@tensorflow/tfjs";
import Canvas from "react-native-canvas";

const TensorCamera = cameraWithTensors(Camera);

const { width, height } = Dimensions.get("window");
let context = useRef<CanvasRenderingContext2D>();
let canvas = useRef<Canvas>();

export default function App() {
  const [model, setModel] = useState<cocoSsd.ObjectDetection>();

  let textureDims =
    Platform.OS === "ios"
      ? { height: 1920, width: 300 }
      : { height: 300, width: 300 };

  function handleCameraStream(images: any) {
    const loop = async () => {
      const nextImageTensor = images.next().value;
      if (!model || !nextImageTensor)
        throw new Error("No model or image tensor");
      model
        .detect(nextImageTensor)
        .then((predictions) => {
          drawRectangle(predictions, nextImageTensor);
        })
        .catch((error) => {
          console.log(error);
        });
      requestAnimationFrame(loop);
    };
    loop();
  }

  function drawRectangle(
    predictions: cocoSsd.DetectedObject[],
    nextImageTensor: any,
  ) {
    if (!context.current || !canvas.current) return;

    const scaleWidth = width / nextImageTensor.shape[1];
    const scaleHeight = height / nextImageTensor.shape[0];

    const flipHorizontal = Platform.OS == "ios" ? false : true;

    context.current.clearRect(0, 0, width, height);

    for (const prediction of predictions) {
      const [x, y, width, height] = prediction.bbox;

      const boundingBoxX = flipHorizontal
        ? canvas.current.width - x * scaleWidth - width * scaleWidth
        : x * scaleWidth;

      const boundingBoxY = y * scaleHeight;

      context.current.strokeRect(
        boundingBoxX,
        boundingBoxY,
        width * scaleWidth,
        height * scaleHeight,
      );

      context.current.strokeText(
        prediction.class,
        boundingBoxX - 5,
        boundingBoxY - 5,
      );
    }
  }

  async function handleCanvas(can: Canvas) {
    if (can) {
      can.width = width;
      can.height = height;
      const ctx: CanvasRenderingContext2D = can.getContext("2d");
      ctx.strokeStyle = "red";
      ctx.fillStyle = "red";
      ctx.lineWidth = 3;

      context.current = ctx;
      canvas.current = can;
    }
  }

  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestPermissionsAsync();
      await tf.ready();
      setModel(await cocoSsd.load());
    })();
  }, []);

  return (
    <View style={styles.container}>
      <TensorCamera
        style={styles.camera}
        type={Camera.Constants.Type.back}
        cameraTextureHeight={textureDims.height}
        cameraTextureWidth={textureDims.width}
        resizeHeight={200}
        resizeDepth={3}
        onReady={handleCameraStream}
        autorender={true}
        useCustomShadersToResize={false}
        resizeWidth={0}
      />
      <Canvas style={styles.canvas} ref={handleCanvas} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
  },
  camera: { width: "100%", height: "100%" },
  canvas: {
    position: "absolute",
    zIndex: 1000000,
    width: "100%",
    height: "100",
  },
});

actual reason for this issue:- You are breaking the Rules of Hooks useRef() should call inside of the component这个问题的实际原因:- 你违反了钩子规则 useRef() 应该在组件内部调用

try this,尝试这个,

...
export default function App() {

  const context = useRef<CanvasRenderingContext2D>();
  const canvas = useRef<Canvas>();

  const [model, setModel] = useState<cocoSsd.ObjectDetection>();
...

}

i think you called useRef outside of the component我认为您在组件之外调用了 useRef

 ... let context = useRef(); let canvas = useRef(); export default function App() {... }

please call useRef inside of your App Component like this请像这样在您的应用程序组件中调用 useRef

 ... export default function App() { let context = useRef(); let canvas = useRef(); ... }

An important rule of using hooks is where you're declaring it.使用钩子的一个重要规则是在哪里声明它。 Hooks can be declared only inside of functions, which is predominantly at the top level, meaning it can only be declared at the top level and not within any nested function, block, or inside another hook(Eg: useEffect ).钩子只能在函数内部声明,主要在顶层,这意味着它只能在顶层声明,而不是在任何嵌套的 function、块或另一个钩子内(例如: useEffect )。 The reason you're getting the error is that you're simply breaking the rules of hooks by declaring it outside of the function.您收到错误的原因是您只是通过在 function 之外声明它来破坏挂钩规则。 Move the hook declaration within the function and you should be good to go.在 function 中移动钩子声明,你应该对 go 很好。 Also, recommend changing let to const as state variables are re-built on every render and not mutated.此外,建议将let更改为const ,因为 state 变量会在每次渲染时重新构建并且不会发生突变。

export default function App() {
  const context = useRef<CanvasRenderingContext2D>();
  const canvas = useRef<Canvas>();
.
.
.
.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM