React-pdf: page-wrapping does not provide totalPages

Created on 30 Jan 2019  路  10Comments  路  Source: diegomura/react-pdf

Describe the bug
When using render prop on Text, the totalPages value is not provided until the second pass.

This would usually be fine (and is appropriately called out in the docs to watch out for), however, if the fixed prop is not defined on Text then render is only called once and 1/undefined gets rendered to the page.

Looks like the second pass render is deliberately skipped if fixed is not supplied. Assuming as a performance optimization. But it seems maybe this is not a valid optimization that can be made.

To Reproduce
Steps to reproduce the behavior including code snippet (if applies):

<Document>
  <Page>
    <Text render={({ totalPages }) => /* totalPages is undefined */} />
</Document>

Expected behavior
Either totalPages should be defined on the first pass, or render should always be called twice.

Screenshots

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: N/A (node)
  • React-pdf version: 1.1.1
bug

Most helpful comment

For anyone running into this problem still, I found this work around:

`

        <View
          fixed={true}
          style={styles.footer}
          render={(props) => {
            console.log('props:', props)
            return (
              <View>
                <Text style={styles.hidden}>{JSON.stringify(props)}</Text>
                <Text
                  style={styles.footerPageNumber}
                  render={(textProps) => {
                    return (
                      <Text>
                        Page {textProps?.pageNumber?.toString()} of{' '}
                        {textProps?.totalPages?.toString()}
                      </Text>
                    )
                  }}
                />
              </View>
            )
          }}
        />

    const styles = StyleSheet.create({
    ...,
    hidden: {
        display: 'none',
        color: styleVars.white,
    },
    ...
})

`
This line is required .. not sure why I keep finding these hacks where rendering props and hiding it causes the component props to be as expected. (Ran into this with react-hook-form library also). In this case, display: none doesn't seem to work, so I blended the stringified props text into the background by changing it to white.

All 10 comments

Thanks for reporting this @arahansen

To be honest I don't remember very well why I as forcing render to be called just once on non-fixed elements. It could be a performance optimization 馃

Anyways, it does not make much sense now, so I'm removing that check. Unfortunately making render to be called just one time would involve a bit much of effort, and I'm not sure even if would be possible, so the only way of fixing this now is by just removing that line 馃槃

Oops. Tests failing. I guess there was a reason why that check, or maybe tests should be fixed.
I have to go now, but I promise I'll take a look at this soon!

I have tried to automatically generate Table of Contents from all headers I render, but when I use this:
<Text style={styles.header1} render={({ pageNumber ) => { tocGenerator.add(value, pageNumber); return value; }} />
It always returns pageNumber = 1 no matter on which page the title appears. Is there any other way or I'm just doing it wrong somehow?

Experiencing this same thing. In a component Implemented like so.
https://gist.github.com/john-raymon/a28a4927881817b45f08e41ff5cb9f1b

Use attribute fixed for <Text />

Yeah I know that. But the point is I don't want (event can't) use fixed attribute. What I'm trying to do is generate Table of Contents from headers so I want them to stay where they are (not fixed) and get only their page number to correctly generate the ToC.

This is way more hard to do than it seems. I'm trying to find a solution in the new upcoming version, but having some issues

With current version, would it be possible to have a fixed Text component with a height and width of zero that wrote table of contents info to state, then have a Table of Contents page draw that info from state? Assuming the page number info is not available until 2nd render, would that even work?

@diegomura any updates on this?

For anyone running into this problem still, I found this work around:

`

        <View
          fixed={true}
          style={styles.footer}
          render={(props) => {
            console.log('props:', props)
            return (
              <View>
                <Text style={styles.hidden}>{JSON.stringify(props)}</Text>
                <Text
                  style={styles.footerPageNumber}
                  render={(textProps) => {
                    return (
                      <Text>
                        Page {textProps?.pageNumber?.toString()} of{' '}
                        {textProps?.totalPages?.toString()}
                      </Text>
                    )
                  }}
                />
              </View>
            )
          }}
        />

    const styles = StyleSheet.create({
    ...,
    hidden: {
        display: 'none',
        color: styleVars.white,
    },
    ...
})

`
This line is required .. not sure why I keep finding these hacks where rendering props and hiding it causes the component props to be as expected. (Ran into this with react-hook-form library also). In this case, display: none doesn't seem to work, so I blended the stringified props text into the background by changing it to white.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

serkyen picture serkyen  路  4Comments

theobat picture theobat  路  3Comments

yellowBanano picture yellowBanano  路  3Comments

kishaningithub picture kishaningithub  路  4Comments

saratonite picture saratonite  路  3Comments