English 中文(简体)
Correct use of ReactToPrint?
原标题:

The problem is that the button that is supposed to give the option to print is not working anymore.

the error in the console says:

To print a functional component ensure it is wrapped with `React.forwardRef`, and ensure the forwarded ref is used. See the README for an example: https://github.com/gregnb/react-to-print#examples

I Have already seen some solutions specifically talking about the same problem but I have not been able to make it work.

any suggestion?

this is the library i m using: ReactToPrint npm

React To print


import { useRef } from "react";
import { useReactToPrint } from "react-to-print";
import Resume from "./Pdf/Pdf";

const  Example = () => {
  const componentRef = useRef();
  const handlePrint = useReactToPrint({
    content: () => componentRef.current
  });
  
  return (
    <div >
    <button onClick={handlePrint}>   ------> NOT WORKING!
      Descargar Pdf
    </button>
    <Resume ref={componentRef} />   ------> COMPONENT TO PRINT
  </div>
  );
};

export default Example;

Component to be printed



 import React from "react";
import styled from  styled-components ;
import PdfSection from  ./PdfSection ;
import AlienLevel from  ./AlienLevel ;
import {connect } from  react-redux ;

class Resume  extends React.Component {
  renderList = () => {
    return this.props.posts.diagnose.map((post) => {
      return (
        <PdfSection
          key={post.id}
          id={post.id}
          divider={"/images/pdf/divider.png"}
          img={"/images/alienRandom.png"}
          title={post.title}
          // data={post.data}
          text={post.text0}
          subtext={post.subtext0}
        />
      );
    });
  };

  render(){

  return (
    <div>
      <Container>
        <Page>
          <Portada>
            <img id="portada" src="/images/pdf/PortadaPdf.png" />
          </Portada>
        </Page>

        <Page>
          <AlienLevel
            result= "{props.diagn}{"
            character={"/images/pdf/alienMedio.png"}
            fileName={"responseBody[4].data"}
            level={"/images/pdf/level6.png"}
            correct={"/images/pdf/correct.png"}
            medium={"/images/pdf/medium.png"}
            incorrect={"/images/pdf/incorrect.png"}
            text= "Necesitas mejorar tus prácticas intergalácticas de CV, pero ya eres nivel medio!" 
          />
          <div>{this.renderList()}</div>
        </Page>
      </Container>
    </div>
  );
};
}
const mapStateToProps = (state) => {
  return { posts: state.posts };
};

export default connect(mapStateToProps)( Resume);

thanks in advance!

问题回答

The problem is with connect() function of react-redux. You wrapped your component in connect and connect by default does not forward ref. Which means, the ref you are passing here <Resume ref={componentRef} /> does not reach to your component.

You need to pass options { forwardRef: true } in fourth parameter of connect function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?).

Just change this code export default connect(mapStateToProps)(Resume); in Resume component to this

export default connect(mapStateToProps, null, null, { forwardRef: true })(Resume);

For anyone that is struggling with the same error, it seems that they found the proper way to resolve this, I actually resolved it by following the Codesandbox I found in the Github issues here si the link. hope is useful! -->

LINK TO GITHUB SPECIFIC ISSUE (SOLVED!!)

I had the same issue and I am happy to share my findings as soon as now. The component has to be rendered somewhere using ref.

I added it to my page as hidden using React Material UI s Backdrop. Or u can hide it using hooks like examples below.

Using backdrop and only calling it when I need to preview the print. ??

<Backdrop sx={{ color: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1 }}
 open={openBD}>
   <ComponentToPrint ref={componentRef} />
</Backdrop>

Using Hooks plus display styling to only display it when needed. ??

const [isReady, setIsReady] = useState("none");

<Paper style={{ display: isReady }} >
 <ComponentToPrint ref={componentRef} />
</Paper>

<Button
 variant="contained"
 endIcon={<BackupTableRoundedIcon />}
 onClick={() => setIsReady("")}
>
  Start Printing
 </Button>

Note: I used MUI components, if u decide to copy paste, then change Button to html <button and paper to <div. Hope this helps.

I was facing the same issue in functional components. I have resolved it myself as following.

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

import MainContentHeader from "./MainContentHeader";
import MainContentBody from "./MainContentBody";

function MainContent(_MUI){
    const componentRef = useRef();
    const handlePrint = useReactToPrint({
        content: ()=> componentRef.current
    })
    return <>
    <_MUI.Stack ref={componentRef} sx={{p:3}} direction="column" alignItems="center">
        <MainContentHeader 
            Grid={_MUI.Grid} 
            Stack={_MUI.Stack} 
            Button={_MUI.Button} 
            Typography={_MUI.Typography} 
            Box={_MUI.Box} />
        <MainContentBody  sx={{mt:2}} />
    </_MUI.Stack>
    <button onClick={handlePrint}>Print</button>
    </>
}
export default MainContent;




相关问题
How to use one react app into another react app?

I have two react apps, parent app and child app. and child app have an hash router. I have build the child app using npm run build, It creates build folder. That build folder moved into inside the ...

how to get selected value in Ant Design

I want to print the selected value, and below is my option list: const vesselName = [ { value: 0 , label: ALBIDDA , }, { value: 1 , label: ALRUMEILA , }, { value: 2 ,...

How to add a <br> tag in reactjs between two strings?

I am using react. I want to add a line break <br> between strings No results and Please try another search term. . I have tried No results.<br>Please try another search term. but ...

热门标签