user3378165
user3378165

Reputation: 6896

Print one of rendered components by map function

I have a Home component that renders with a map function an array of contacts, each contact has its own print button and should print only its contact . The issue is that currently it prints the entire page and not just the contact which the print was clicked on.

I added a isPrinting state to the contact component, by default set to false, when the print button is being clicked it's being set to true and when the print dialog is being closed I set it back to false.

How can I actually make the print button to print only the contact that its print was click?

My handlePrint function on contact component:

  handlePrint = () => {
    this.setState({ isPrinting: true });
    window.print();
    window.onafterprint(
      this.setState({ isPrinting: false })
    );
  };

map function on Home component:

  contacts.map(info => (
              <SearchResultsPanel
                info={info}
                key={info.id}
              />

I'm using '@media print' to control the print styles.

Upvotes: 0

Views: 473

Answers (1)

Lo&#239;c Goyet
Lo&#239;c Goyet

Reputation: 750

What I would do is to by default hide on @media print every Contact component you display.

Then into your <SearchResultsPanel> component instance that you want to print out make append a css class that would override the display: none declaration that affect all the contact, using the isPrinting state you setup in this specific instance.

You also may want to use callbacks on setState to make sure the re-render caused by this.setState({ isPrinting: true }); is done before the window.print() is triggered.

So you could do :

handlePrint = () => {
    this.setState({ isPrinting: true }, () => {
        window.print();
        window.onafterprint(
            this.setState({ isPrinting: false })
        );
    });
};

or if you want to use hooks :

import {useEffect, useState} from 'react';

// Set isPrinting value and its setter function
const [isPrinting, setIsPrinting] = useState(false)

// Your handlePrint function reshaped for hooks
const handlePrint = () => setIsPrinting(true)

// Callback when isPrinting is updated to true
useEffect(() => {
    if (isPrinting) {
        window.print();
        window.onafterprint(setIsPrinting(false));
    }
}, [isPrinting])

Upvotes: 1

Related Questions