diegomura / react-pdf

📄 Create PDF files using React
https://react-pdf.org
MIT License
14.94k stars 1.18k forks source link

Use Suspense #1731

Open tarabishy2020 opened 2 years ago

tarabishy2020 commented 2 years ago

There seems to be two issues mentioning Suspense - #905 and #936, but with no resolution.

I am using react-pdf in node, and I was hoping that the following would work

import React, { Suspense } from "react";
import { Page, View, Text} from "@react-pdf/renderer";
import { suspend } from "suspend-react";
import fetch from "node-fetch";

const fetchHN = async () => {
  return await (await fetch("https://hacker-news.firebaseio.com/v0/item/8863.json")).json();
};

const SomeText = () => {
  const data = suspend(async () => {return await fetchHN();}, []);
  return <Text>{JSON.stringify(data)}</Text>;
};
const Doc=()=>{
return (
    <Page>
      <View>
        <Suspense fallback={null}>
          <SomeText />
        </Suspense>
      </View>
    </Page>
)
}

But I am getting

TypeError: unhideInstance is not a function
at hideOrUnhideAllChildren (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:12231:11)        
at commitSuspenseComponent (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:13105:5)       
at commitWork (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:13031:9)
at commitMutationEffects (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:15295:11)        
at Object.invokeGuardedCallbackImpl (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:11552:1010)
at invokeGuardedCallback (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:11729:31)        
at commitRootImpl (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:15028:9)
at unstable_runWithPriority (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\node_modules\scheduler\cjs\scheduler.development.js:s:818:12)
at runWithPriority (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:1884:10)
at commitRoot (..\node_modules\@react-pdf\renderer\node_modules\react-reconciler\cjs\react-reconciler.development.js:14909:3)

I also saw #1523, but parity in terms of how react deals with suspense would resolve this without having to add an extra Primitive.

ShanonJackson commented 9 months ago

Have a similar use case.

I want to start a async file download (via the browser file download API) and be able to leave the webpage while the download is continuing in the background.

To achieve this in Node I have to send at least 1 byte to the browser in a stream and return the correct headers. The problem is that to generate the PDF I need to perform a request to get additional data, and therefore I can't send 1 byte until the request completes; And unfortunately due to factors outside my control the request can take long periods of time.

Think Suspense helps in this case because I can renderToStream instantly returning the parts of the PDF that are static (thus returning 1 byte to the browser immediately kicking off the download, then stream the dynamic parts through as they're ready but the user can now close the tab or leave the website and the PDF download will still complete.