【问题标题】:How to use react-pdf library with Typescript如何在 Typescript 中使用 react-pdf 库
【发布时间】:2019-02-22 03:07:28
【问题描述】:

我正在尝试使用一个 npm 库来帮助我呈现 pdf 文档。我找到了 react-pdf 但它还没有 TypeScript 的类型,所以我正在使用它,如下所示:

let Document = require('react-pdf');
let Page = require('react-pdf');

class PdfViewer extends React.Component<PdfViewer.Props, PdfViewer.State> {

  constructor(props: PdfViewer.Props) {
    super(props);
    this.state = {
      numPages: null,
      pageNumber: 1,
    };

  }
  onDocumentLoadSuccess = ( numPages: number ) => {
    this.setState({ numPages });

  }

  componentWillReceiveProps(nextProps: PdfViewer.Props) {
    // this.setState(CsvViewer.parse(nextProps.data));
  }

  render() {
      const {url} = this.props;
      const { pageNumber, numPages } = this.state;

      const buffer = data as ArrayBuffer;

      return ( 
      <div>
        <Document
          file={url}
          onLoadSuccess={this.onDocumentLoadSuccess}
        >
          <Page pageNumber={pageNumber} />
        </Document>
        <p>Page {pageNumber} of {numPages}</p>
      </div>
      );

  }
}

但它抛出了这个错误:

元素类型无效:应为字符串(用于内置组件) 或类/函数(用于复合组件)但得到:对象。

我在 GitHub 中找到了this,但对我没有多大帮助。 我去了图书馆的documentation,我在文件参数中传递了一个对象,正如他们展示的那样,但同样的错误。我认为是另外一回事。 我去了react-pdf库的源代码,我认为这是他们用来从参数中获取文件的函数:

findDocumentSource = async () => {
    const { file } = this.props;

    if (!file) {
      return null;
    }

    // File is a string
    if (typeof file === 'string') {
      if (isDataURI(file)) {
        const fileUint8Array = dataURItoUint8Array(file);
        return { data: fileUint8Array };
      }

      displayCORSWarning();
      return { url: file };
    }

    // File is PDFDataRangeTransport
    if (file instanceof PDFDataRangeTransport) {
      return { range: file };
    }

    // File is an ArrayBuffer
    if (isArrayBuffer(file)) {
      return { data: file };
    }

    /**
     * The cases below are browser-only.
     * If you're running on a non-browser environment, these cases will be of no use.
     */
    if (isBrowser) {
      // File is a Blob
      if (isBlob(file) || isFile(file)) {
        return { data: await loadFromFile(file) };
      }
    }

    // At this point, file must be an object
    if (typeof file !== 'object') {
      throw new Error('Invalid parameter in file, need either Uint8Array, string or a parameter object');
    }

    if (!file.url && !file.data && !file.range) {
      throw new Error('Invalid parameter object: need either .data, .range or .url');
    }

    // File .url is a string
    if (typeof file.url === 'string') {
      if (isDataURI(file.url)) {
        const { url, ...otherParams } = file;
        const fileUint8Array = dataURItoUint8Array(url);
        return { data: fileUint8Array, ...otherParams };
      }

      displayCORSWarning();
    }

    return file;
  };

但我怀疑错误是否在这里,但我无法弄清楚可能是什么。我使用的react 的版本是16.8.2 和react-pdf 的4.0.2

【问题讨论】:

    标签: reactjs typescript react-pdf


    【解决方案1】:

    这是不正确的:

    let Document = require('react-pdf');
    let Page = require('react-pdf');
    

    执行此操作时,您正在导入 整个 模块。这意味着DocumentPage 都包含react-pdf 的所有模块。相反,您想要做的是导入 ReactPDF 并引用这些模块:

    const ReactPDF = require('react-pdf');
    
    <ReactPDF.Document />
    <ReactPDF.Page />
    

    你可以使用解构:

    import { Document, Page } from 'react-pdf';
    
    //or
    
    const { Document, Page } = require('react-pdf'); 
    

    如果 TypeScript 抱怨缺少声明,只需在您的项目中添加一个 @types 文件夹,在其中创建一个名为 react-pdf 的子文件夹,并在该文件夹内创建一个名为 index.d.ts 的文件,其中包含一行:

    declare module "react-pdf"
    

    【讨论】:

    • 让我试试
    • 我现在尝试了您的第二个建议,但我得到了这个:` 如果存在,请尝试 npm install @types/react-pdf,或者添加一个包含 declare module 'react-pdf' 的新声明 (.d.ts) 文件。我在src文件夹中创建了@types文件夹,我应该把它放在node_modules的同级之外吗?
    • 我总是把我的放在 src 中,所以完整路径是 ./src/@types/react-pdf/index.d.ts 但我不确定它在哪里是否真的很重要
    • 我的错,我停下来重新开始这个项目,它成功了,再次感谢
    • 感谢您提供有关修复缺失类型声明的信息!
    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2018-11-03
    • 2020-09-05
    相关资源
    最近更新 更多