@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지영
相关产品推荐
相关产品推荐

