react-to-print: UpdatedDom ignored on onbeforeprint

Hi, I am using this lines

<ReactToPrint
  trigger={() => <a href="#">Print this out!</a>}
  content={() => componentRef.current}
  onBeforePrint={() => setPrintMode(true)}
  onAfterPrint={() => setPrintMode(false)}
/>

where i am setting Printmode to true, in order to render additional Content (Legend) for the print.

{printMode &&
  <div>
    {data.legende.map((l) => <div>{`${l.abk}: ${l.text}`}</div>)}
  </div>
}

However. It is called and the DOM updated (as i can see in the background, but in the print window it still shows the “non-print-version”.

the full thing I use:

const componentRef = useRef();

return (
  <div className={css(styles.formsContainer)} ref={componentRef} >
    <h2 className={styles.formsTitle}>
      {Strings.PressespiegelHeaderText}
      {!printMode &&
        <ReactToPrint
          trigger={() => <a href="#">Print this out!</a>}
          content={() => componentRef.current}
          onBeforePrint={() => setPrintMode(true)}
          onAfterPrint={() => setPrintMode(false)}
        />
      }
      </h2>
      {data &&
        <div>
          {`Ausgabe vom ${data.datum}`}
          {data.kapitel.slice(1).map((kapitel) => {
            return (
              <div key={kapitel.id}>
                <div>
                  {kapitel.bezeichnung}
                </div>
                <ListBase
                  hideArrow
                  items={kapitel.KM}
                  renderItem={renderKM}
                />
              </div>
            );
          })}
          {printMode &&
            <div>
              {data.legende.map((l) => <div>{`${l.abk}: ${l.text}`}</div>)}
            </div>}
            {data.copyright}
        </div>
      }
    </div>
);`

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 24 (13 by maintainers)

Most upvoted comments

I personally think the simplest solution is for onBeforePrint to optionally return a Promise that we will wait to be resolved before printing. That way the user can decide however they would like when/how to resolve the Promise.

The proposal you’ve suggested with waiting for componentDidUpdate to run won’t work because it won’t have any knowledge of async calls within the lifecycle methods of child components. For example, if a child component renders some temporary state and makes a network call, and then will re-render when the network call finishes, componentDidUpdate will still fire because it does not know about the pending Promise.

Promise is a widely supported library that just about everyone doing JS these days should be knowledgeable with. Other than requiring a browser polyfill for older browsers (which I would guess most users are already doing if they support those browsers), I don’t see any downside to it.