使用 React 未处理的拒绝(错误)创建 Pdf:在结束后写入

Create Pdf Using React Unhandled Rejection (Error): write after end

描述错误

大家好, 我正在尝试生成包含一些 user-provided 信息的 PDF。特别是,我希望我的用户选择 pdf 的文件名,这也是它的标题。 为此,我使用:

"@react-pdf/renderer": "^1.6.12" for the pdf rendering "react-bootstrap": "^1.3.0" for the page layout "formik": "^2.2.0" for form management

我遇到的问题在于,每当用户开始在适当的输入中输入所需的 filename/title 时,页面就会崩溃并出现以下错误:

Unhandled Rejection (Error): write after end
3 stack frames were expanded.
writeAfterEnd
node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js:288
(anonymous function)
node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js:332
addContent
node_modules/@react-pdf/pdfkit/dist/pdfkit.browser.es.js:4184 

经过更深入的调查,我注意到问题出在生成的 pdf 内容的“动态性”上。

代码如下:

const DownloadModal = ({configuration}) => {
    const [show, setShow] = useState(false);

    const formik = useFormik({
        initialValues: {
            name: "",
        }
    });

    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);


    return (
        <>
            <Button variant="primary"
                    onClick={() => {
                        handleShow()
                    }}
            >
                Download PDF <DownloadIcon/>
            </Button>

            <Modal size={"lg"} show={show} onHide={handleClose} animation={true}>
                <Modal.Header closeButton>
                    <Modal.Title>Choose filename</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <Form onSubmit={(event) => {
                        event.preventDefault();
                    }}>
                        <Form.Group as={Row}>
                            <Form.Label column sm={2}>
                                Filename
                            </Form.Label>
                            <Col sm={10}>
                                <InputGroup className="mb-3">
                                    <FormControl
                                        type="text"
                                        id={"name"}
                                        name={"name"}
                                        placeholder="filename"
                                        onChange={formik.handleChange}
                                        value={formik.values.name}
                                        autoComplete={"off"}
                                    />
                                    <InputGroup.Append>
                                        <InputGroup.Text id="basic-addon2">.pdf</InputGroup.Text>
                                    </InputGroup.Append>
                                </InputGroup>
                            </Col>
                        </Form.Group>
                    </Form>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={handleClose}>
                        Close
                    </Button>
                    <DownloadPDFButton
                        data={configuration}
                        title={formik.values.name}
                    />
                </Modal.Footer>
            </Modal>
        </>
    );
};
const DownloadPDFButton = ({data, title}) => {

    return (
        <PDFDownloadLink
            document={
                <PdfDocument
                    data={data}
                    title={{title}}
                />}
            fileName={`${title}.pdf`}
            className={"btn btn-link"}
        >
            {({blob, url, loading, error}) =>
                loading ? <Spinner animation="border" variant="primary"/> : "Download"
            }
        </PDFDownloadLink>
    )
}

我认为问题出在我显示的方式上 title.title。但是我真的找不到办法让它工作。

const Title = ({title}) => {
        return (
            <View style={styles.titleContainer}>
                <Text>{title.title}</Text>
            </View>

        )
    }
;

const PdfDocument = (props) => {

    const configurationData = {
        plant: props.data.plant,
        flow: props.data.flow,
        optionals: props.data.optionals
    };

    const utilitiesData = {
        total_installed_power: props.data.total_installed_power,
        total_absorbed_power: props.data.total_absorbed_power,
        makeup_water: props.data.makeup_water,
        compressed_air: props.data.compressed_air
    };

    return (
        <Document>
            <Page key={"page-0"} style={styles.page}>
                <Image style={styles.logo} src={logo}/>
                <Title title={props.title}/>
                <ConfigurationPDF configuration={configurationData}/>
                <ResultsPDF results={utilitiesData}/>
            </Page>
        </Document>
    );
};

先谢谢大家!!

运行环境:

我想你的问题现在已经解决了

我只把formik state转换成react state

Codesandbox:https://codesandbox.io/s/reverent-browser-1bn4n