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

@react-pdf/renderer在Mac/iOS端异常:滚动后白屏问题求助

问题描述

使用@react-pdf/renderer开发PDF生成功能时,Windows端运行正常,但Mac和iOS端仅初始加载正常,滚动后变为白屏;Mac上用Chrome打开PDF显示正常,但用预览应用打开则出现白屏。更换@react-pdf/renderer版本也无法解决该问题。

相关代码

import styled from "styled-components";
import Spacer from "../Spacer";
import React from "react";
import {Document, Image, Page, PDFDownloadLink, StyleSheet, View, PDFViewer} from "@react-pdf/renderer";
import uuid from "react-uuid";
import {Model} from "../../models/interfaces/Model";

interface AdditionalMenuProps {
    models: Model[]
    sendEmailOnClick?: () => void
}

const S = {
    Container: styled.div`
      width: calc(100% - 12px);
      display: flex;
      padding: 12px 8px;
      flex-direction: row;
      border-bottom: 1px solid white;
      
    `,
    Menu: styled.div`
      cursor: pointer;
      font-family: Jura, sans-serif;
      font-size: 16px;
      font-weight: 300;
      color: white;
    `,
    Divider: styled.div`
        height: 12px;
      background-color: white;
      width: 1px;
      color: white;
    `
}

const styles = StyleSheet.create({

    page: {
        display: "flex",
        backgroundColor: 'black',
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    container: {
        display: "flex",
        flexDirection: "column",
        justifyContent: "center",
        alignItems: "center"
    },
    image: {
        width: 300,
        padding: 10,
        marginTop: 80,
    },
    logo: {
        width: 60
    },
    compCard: {
        width: 880,
        height: 560,
        objectFit: "contain"
    }
});

const AdditionalMenu:React.FC<AdditionalMenuProps> = ({models,
                                                      sendEmailOnClick}) => {


    const document = <Document>
        {
            models?.map((model) => {
                return <Page size="A4" style={styles.page} key={uuid()} orientation={"landscape"}>
                    <View style={styles.container}>
                        <Image src={{
                            uri: model?.comCardImageUrl,
                            method: 'GET',
                            headers: {"Cache-Control": "no-cache"},
                            body: ''
                        }} style={styles.compCard}/>
                    </View>
                </Page>
            })
        }
    </Document>


    return (<S.Container>
        <PDFDownloadLink document={document} fileName={'models'} style={{textDecoration: "none"}}>
            <S.Menu>
                PDF DOWNLOAD
            </S.Menu>
        </PDFDownloadLink>
        <Spacer width={20}/>
        <S.Divider/>
        <Spacer width={20}/>
        <S.Menu onClick={sendEmailOnClick}>CONTACT</S.Menu>
    </S.Container>)
}

export default AdditionalMenu
问题分析与解决方案

这个问题核心是跨平台PDF渲染引擎的兼容性差异,结合代码和现象,可从以下几个方向解决:

1. 图片资源加载兼容性

Mac/iOS的PDF阅读器(如预览应用)对远程图片的加载逻辑和Windows不同,no-cache设置可能导致滚动时图片无法重新渲染。建议将远程图片转为base64后再传入:

// 新增图片转base64工具函数
async function getBase64Image(url) {
  const response = await fetch(url);
  const blob = await response.blob();
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}

// 在组件中提前加载并转换图片
const AdditionalMenu:React.FC<AdditionalMenuProps> = ({models, sendEmailOnClick}) => {
  const [base64Images, setBase64Images] = React.useState<string[]>([]);

  React.useEffect(() => {
    async function loadImages() {
      if (!models?.length) return;
      const images = await Promise.all(models.map(m => getBase64Image(m.comCardImageUrl)));
      setBase64Images(images);
    }
    loadImages();
  }, [models]);

  const document = <Document>
    {base64Images.map((img, index) => {
      return <Page size="A4" style={styles.page} key={models[index].id || index} orientation={"landscape"}>
        <View style={styles.container}>
          <Image src={img} style={styles.compCard}/>
        </View>
      </Page>
    })}
  </Document>

  // 其余代码不变
}

2. 布局兼容调整

@react-pdf/renderer的flex布局在Mac预览应用中支持不完善,改用绝对定位实现居中:

const styles = StyleSheet.create({
  page: {
    backgroundColor: 'black',
    position: 'relative',
  },
  container: {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
  },
  // 其余样式不变
});

3. 修正Page组件的key值

使用uuid()会导致每次渲染生成新key,可能引发渲染不稳定,改用model的唯一标识或索引:

models?.map((model, index) => {
  return <Page size="A4" style={styles.page} key={model.id || index} orientation={"landscape"}>
    {/* ... */}
  </Page>
})

4. 适配页面尺寸

你设置的图片宽度880px超过了A4横向页面的实际宽度(约842px),可能导致渲染异常,调整图片尺寸:

compCard: {
  width: '95%',
  maxWidth: 800,
  height: 'auto',
  objectFit: "contain"
}

内容的提问来源于stack exchange,提问作者blair지영

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:23:12