You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用useMemo后react-pdf仍随父组件重复渲染问题求助

问题分析与解决步骤

1. 修复PDFView组件的props接收问题

你的PDFView组件定义中未接收props参数,导致props.file无法正确获取,先修正这个基础错误,同时用React.memo包裹组件缓存渲染结果:

import { Document, Page } from 'react-pdf';
import React from 'react';

// 接收props参数
const PDFView = (props) => {
    
  return (
    <Document file={props.file}>
      <Page width={100} height={100}></Page>
    </Document>
  );
};

// 用React.memo包裹,避免无意义重渲染
export default React.memo(PDFView);

2. 修正父组件DropBox的useMemo误用

你当前直接用useMemo调用Dropbox()的方式错误,这会每次渲染都生成新组件实例,正确做法是用React.memo包裹DropBox组件,并保证传递的props引用稳定:

import React from 'react';
import PDFView from './PDFView';

// 用React.memo包裹DropBox组件
const DropBox = React.memo(({ file, preview, type, hasFile }) => {
  return (
    <>
      {hasFile && (
        type === 'application/pdf' ?
          <PDFView file={file} />
          :
          <img alt="" src={preview} />
      )}
    </>
  );
}, (prevProps, nextProps) => {
  // 自定义props比较逻辑,针对file这类复杂对象,避免因引用变化触发重渲染
  if (prevProps.file instanceof File && nextProps.file instanceof File) {
    return prevProps.file.name === nextProps.file.name && prevProps.file.size === nextProps.file.size;
  }
  // 基础类型直接比较
  return prevProps.file === nextProps.file 
    && prevProps.preview === nextProps.preview 
    && prevProps.type === nextProps.type 
    && prevProps.hasFile === nextProps.hasFile;
});

export default DropBox;

3. 确保上层组件传递的props稳定

在使用DropBox的上层组件中,若file是动态生成的对象,用useMemo缓存其引用,避免每次渲染生成新引用触发子组件重渲染:

const ParentComponent = () => {
  // 缓存file引用,仅在依赖项变化时更新
  const file = useMemo(() => {
    // 示例:如果是文件上传获取的File对象,直接使用即可;如果是自定义对象,在这里缓存
    return yourFileInstance;
  }, [yourFileInstance]); // 根据实际依赖项设置

  const preview = 'example.png';
  const type = 'application/pdf';
  const hasFile = true;

  return (
    <DropBox file={file} preview={preview} type={type} hasFile={hasFile} />
  );
};

4. 优化react-pdf加载状态(可选)

若仍出现重复显示"Loading PDF",可手动缓存加载状态,避免重复触发:

import { Document, Page } from 'react-pdf';
import React, { useState } from 'react';

const PDFView = React.memo((props) => {
  const [isLoading, setIsLoading] = useState(true);

  return (
    <Document
      file={props.file}
      onLoadSuccess={() => setIsLoading(false)}
      onLoadError={() => setIsLoading(false)}
    >
      {isLoading ? <div>Loading PDF</div> : <Page width={100} height={100} />}
    </Document>
  );
});

export default PDFView;

核心问题总结

  • PDFView组件未接收props,导致文件无法正确传递;
  • 错误使用useMemo直接调用组件函数,组件记忆化应使用React.memo;
  • 未保证file等props的引用稳定,引发子组件不必要重渲染。

内容的提问来源于stack exchange,提问作者Sapir Yermiyahu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:55:20