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):
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
Most helpful comment
For anyone running into this problem still, I found this work around:
`
` .. 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.
This line is required