React component printing with react-to-print

Print Perfect: Unleashing the Magic of react-to-print

The Gray Cat
The Gray Cat

React applications often require the ability to print specific components or sections of a page. While browsers provide a basic printing functionality, it often falls short when it comes to preserving the layout and styling of complex React components. Enter react-to-print, a powerful library that bridges this gap, allowing developers to create pixel-perfect printouts of their React components with ease.

Unveiling the Power of react-to-print

react-to-print is a versatile npm package that enables you to print the content of React components while maintaining their styles and layout. It works by creating a hidden iframe, copying the styles and content of your component into it, and then triggering the browser’s print functionality on that iframe. This approach ensures that your printed output closely matches what you see on the screen.

Key Features

react-to-print comes packed with a range of features that make it a go-to solution for printing in React applications:

  • Preserves styles and layout of React components
  • Supports both class and functional components
  • Allows customization of print settings
  • Provides callbacks for various stages of the print process
  • Handles complex scenarios like printing scrollable content
  • Offers TypeScript support for type-safe development

Getting Started with react-to-print

Let’s dive into how you can integrate react-to-print into your React project and start printing components with ease.

Installation

To begin, install the package using npm or yarn:

npm install react-to-print
# or
yarn add react-to-print

Basic Usage

Here’s a simple example of how to use react-to-print with a functional component:

import React, { useRef } from 'react';
import { useReactToPrint } from 'react-to-print';

const ComponentToPrint = React.forwardRef((props, ref) => {
  return (
    <div ref={ref}>
      <h1>Printable Content</h1>
      <p>This content will be printed!</p>
    </div>
  );
});

const PrintExample = () => {
  const componentRef = useRef();
  const handlePrint = useReactToPrint({
    content: () => componentRef.current,
  });

  return (
    <div>
      <ComponentToPrint ref={componentRef} />
      <button onClick={handlePrint}>Print this out!</button>
    </div>
  );
};

In this example, we define a ComponentToPrint that contains the content we want to print. We then use the useReactToPrint hook to create a handlePrint function, which we attach to a button. When clicked, it triggers the printing process for the referenced component.

Advanced Usage

react-to-print offers various options to customize the printing process. Let’s explore some advanced use cases.

Custom Page Styles

You can apply custom styles to the printed page using the pageStyle option:

const handlePrint = useReactToPrint({
  content: () => componentRef.current,
  pageStyle: `
    @page {
      size: A4;
      margin: 20mm;
    }
    @media print {
      body {
        -webkit-print-color-adjust: exact;
      }
    }
  `,
});

This example sets the page size to A4 and adds margins, while also ensuring color accuracy in the printout.

Handling Asynchronous Content

If your component loads data asynchronously, you can use the onBeforePrint callback to ensure all content is loaded before printing:

const [isDataLoaded, setIsDataLoaded] = useState(false);
const promiseResolveRef = useRef(null);

useEffect(() => {
  if (isDataLoaded && promiseResolveRef.current) {
    promiseResolveRef.current();
  }
}, [isDataLoaded]);

const handlePrint = useReactToPrint({
  content: () => componentRef.current,
  onBeforePrint: () => {
    return new Promise((resolve) => {
      promiseResolveRef.current = resolve;
      loadAsyncData().then(() => setIsDataLoaded(true));
    });
  },
});

This setup ensures that the printing process waits for the asynchronous data to load before proceeding.

Printing Scrollable Content

When dealing with scrollable content, you might need to adjust the container’s properties to ensure all content is visible in the printout:

const customPrint = (printWindow) => {
  const printContent = printWindow.contentDocument;
  const printedScrollContainer = printContent.querySelector('.scroll-container');

  printedScrollContainer.style.overflow = 'visible';
  printedScrollContainer.style.height = 'auto';

  printWindow.contentWindow.print();
};

const handlePrint = useReactToPrint({
  content: () => componentRef.current,
  print: customPrint,
});

This custom print function modifies the scrollable container to show all its content in the printout.

Best Practices and Tips

To get the most out of react-to-print, keep these tips in mind:

  1. Use Media Queries: Leverage CSS media queries to define print-specific styles:
@media print {
  .no-print {
    display: none;
  }
  .page-break {
    page-break-before: always;
  }
}
  1. Handle Page Breaks: Use CSS properties like break-inside, break-before, and break-after to control where page breaks occur in your printed document.

  2. Test Across Browsers: Print behavior can vary between browsers, so test your print functionality across different browsers to ensure consistency.

  3. Optimize for Print: Consider creating a print-optimized version of your component that omits unnecessary elements and adjusts layouts for better print readability.

  4. Use Font Loading: If you’re using custom fonts, ensure they’re loaded before printing to avoid font rendering issues in the printout.

Conclusion

react-to-print is a powerful tool that simplifies the process of printing React components while maintaining their visual integrity. By leveraging its features and following best practices, you can create high-quality, pixel-perfect printouts directly from your React applications. Whether you’re generating invoices, reports, or any other printable content, react-to-print provides the flexibility and control you need to deliver professional results.

As web applications continue to evolve, the ability to seamlessly bridge the digital and physical worlds through printing remains crucial. With react-to-print, you have a reliable ally in creating print-friendly React applications that look great both on screen and on paper.

Comments