reactjstypescriptreact-pdfreact-pdfrenderer

How to pass props to react-pdf/renderer renderToStream function?


I am trying to render a pdf to sent it as an attachment with Resend.

This is my test PDF. Basically the one from the docs from react-pdf/renderer but with one testprop added.

import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer'

const styles = StyleSheet.create({
  page: {
    flexDirection: 'row',
    backgroundColor: '#E4E4E4',
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1,
  },
})

export const TestPDF = ({ message }: { message: string | undefined }) => (
  <Document>
    <Page size='A4' style={styles.page}>
      <View style={styles.section}>
        <Text>{message ?? 'No message'}</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
)

I am trying to renderToStream as follows:

let stream = await renderToStream(createElement(TestPDF, { message }))

It works fine when there's no message prop and I just render the TestPDF. The minute I add a prop it stops working and says this:

Argument of type 'FunctionComponentElement<{ message: string | undefined; }>' is not assignable to parameter of type 'ReactElement<DocumentProps, string | JSXElementConstructor<any>>'.
  Types of property 'props' are incompatible.
    Type '{ message: string | undefined; }' has no properties in common with type 'DocumentProps'.ts(2345)

If I would add the TestPDF as a component like this:

let stream = await renderToStream(<TestPDF message={message} />)

It says this:

'TestPDF' refers to a value, but is being used as a type here. Did you mean 'typeof TestPDF'?

So that also doesn't seem to be the solution.


Solution

  • Make sure the file where you're calling let stream = await renderToStream(<TestPDF message={message} />) has the .tsx extension. If the file has a .ts extension, you’ll get the error: 'TestPDF' refers to a value, but is being used as a type here. Did you mean 'typeof TestPDF'?

    As a rule of thumb:

    1. Use .ts for files containing only TypeScript.
    2. Use .tsx for files containing JSX.