无效的钩子调用 - useState 函数

时间:2021-02-26 07:04:14

标签: reactjs

我刚接触 js 并遇到以下错误:

<块引用>

错误:无效的挂钩调用。 Hooks 只能在 body 内部调用 一个功能组件。这可能发生在以下情况之一 原因:

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 你可能违反了钩子规则
  3. 您可能在同一个应用中拥有多个 React 副本,请参阅 https://reactjs.org/link/invalid-hook-call 以获取有关如何调试的提示 并解决这个问题

失败的那一行:

const [scale, setScale] = useState(initialScale);

代码片段在这里:

import React, {
  useMemo,
  useState,
  useEffect,
  useCallback,
  useImperativeHandle,
  forwardRef,
  Ref,
} from 'react';
import usePDF from './hooks/usePDF';
import useAnnotations from './hooks/useAnnotations';
import useTextMap from './hooks/useTextMap';
import Page from './components/Page';
import Error from './components/Error';
import ButtonGroup from './components/ButtonGroup';
import { Entity } from './interfaces/entity';
import { Annotation } from './interfaces/annotation';
import { TextLayer, TextLayerItem } from './interfaces/textLayer';
import { debug } from 'console';

interface Props {
  url?: string;
  data?: Uint8Array | BufferSource | string;
  httpHeaders?: {
    [key: string]: string;
  };
  initialScale?: number;
  tokenizer?: RegExp;
  disableOCR?: boolean;
  entity?: Entity;
  initialTextMap?: Array<TextLayer>;
  defaultAnnotations?: Array<Annotation>,
  getAnnotations(annotations: Array<Annotation>): void
  getTextMaps?(textMaps: Array<TextLayer>): void;
}

const Annotator = forwardRef(({
  url,
  data,
  httpHeaders,
  initialScale = 1.5,
  tokenizer = new RegExp(/\w+([,.\-/]\w+)+|\w+|\W/g),
  disableOCR = false,
  entity,
  initialTextMap,
  defaultAnnotations = [],
  getAnnotations,
  getTextMaps,
}: Props, ref?: Ref<any>) => {
  const [scale, setScale] = useState(initialScale);

  const { pages, error, fetchPage } = usePDF({ url, data, httpHeaders });
  const {
    annotations,
    getAnnotationsForPage,
    addAnnotation,
    removeAnnotation: deleteAnnotation
  } = useAnnotations(defaultAnnotations);
  const { textMap, addPageToTextMap } = useTextMap(annotations);

  useImperativeHandle(ref, () => ({ removeAnnotation }));

  const removeAnnotation = (id: string) => {
    deleteAnnotation(id);
  };

  useEffect(() => {
    if (getAnnotations) {
      getAnnotations(annotations);
    }
    if (getTextMaps) {
      getTextMaps(initialTextMap || textMap);
    }
  }, [annotations, textMap, initialTextMap, getAnnotations, getTextMaps]);

  const getTextLayerForPage = useCallback((page: number): Array<TextLayerItem> | undefined => {
    if (initialTextMap) {
      const found = initialTextMap.find((layer) => layer.page === page);
      return found ? found.textMapItems : undefined;
    }
    return undefined;
  }, [initialTextMap]);

  const renderPages = useMemo(() => {
    if (!url && !data) {
      return (
        <Error
          message="You need to provide either valid PDF data or a URL to a PDF"
        />
      );
    }
    console.log('i am here')
    debugger
    // if (error) {
    //   return <Error />;
    // }

    return (
      Array(pages).fill(0).map((_, index) => {
        const key = `pdf-page-${index}`;
        const pageNumber = index + 1;
        const page = fetchPage(pageNumber);
        return (
          <Page
            page={page}
            scale={scale}
            key={key}
            tokenizer={tokenizer}
            disableOCR={disableOCR}
            pageNumber={pageNumber}
            annotations={getAnnotationsForPage(pageNumber)}
            addAnnotation={addAnnotation}
            removeAnnotation={deleteAnnotation}
            addPageToTextMap={addPageToTextMap}
            entity={entity}
            initialTextLayer={getTextLayerForPage(pageNumber)}
          />
        );
      })
    );
  }, [
    url, data, pages, error, scale, tokenizer, disableOCR, entity,
    fetchPage, getAnnotationsForPage, addAnnotation, deleteAnnotation, addPageToTextMap, getTextLayerForPage,
  ]);

  return (
    <div className="annotator-container">
      <div className="annotator-pages-container">
        <div className="annotator-pages">
          { renderPages }
        </div>
      </div>
      <ButtonGroup scale={scale} setScale={setScale} />
    </div>
  );
});

export default Annotator;



0 个答案:

没有答案