0

我正在将 React 与react-pdf一起使用,并尝试将 PDF 呈现到我的模式中。但是,我的模式会在单击按钮时加载,因此不会在应用程序加载时加载。但它试图在应用程序加载时调用 PDF 渲染调用,从而产生错误:“错误:目标容器不是 DOM 元素”。我不确定如何解决这个问题。

这是我的整个模态组件:

import ReactModal from 'react-modal';
import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactPDF, { PDFViewer } from '@react-pdf/renderer';
import CloseButton from './CloseButton';
import MessageHub from '../message/MessageHub';
import PDFPlacard from '../placards/PDFPlacard';

const PDF = () => (
    <PDFViewer>
        <PDFPlacard />
    </PDFViewer>
);

const PlacardsModal = (props) => {
    const { openPlacards, setOpenPlacards, customStyles } = props;
    const numPlacards = React.createRef();

    const ref = useRef(null);

    // this call needs to happen after the modal and #PDFPlacard is rendered
    ReactDOM.render(<PDF />, document.getElementById('PDFPlacard'));

    const handleSubmit = (evt) => {
        evt.preventDefault();
        if (numPlacards.current.value === '') {
            ref.current('Please fill in the number of placards.');
        } else {
            // submit form
        }
    };

    return (
        <ReactModal
            isOpen={openPlacards}
            style={customStyles}
            className={'print-placards-modal'}
            closeTimeoutMS={1000}
        >
            <CloseButton setOpenModal={setOpenPlacards} />
            <h2>Print Placards</h2>
            {/* eslint-disable-next-line react/no-children-prop */}
            <MessageHub children={(add) => (ref.current = add)} />
            <form className={'form'} onSubmit={handleSubmit}>
                <div className={'form-group row'}>
                    <label
                        htmlFor={'numPlacards'}
                        className={'col-sm-6 col-form-label'}
                    >
                        Number of Placards:
                    </label>
                    <div className={'col-sm-6'}>
                        <input
                            id={'numPlacards'}
                            type={'number'}
                            className={'form-control'}
                            ref={numPlacards}
                        />
                    </div>
                </div>
                <button
                    className={'btn btn-primary d-block mx-auto mb-2'}
                    type={'submit'}
                    value={'Print'}
                />
            </form>
            <div id={'PDFPlacard'} />
        </ReactModal>
    );
};

PlacardsModal.propTypes = {
    openPlacards: PropTypes.bool,
    setOpenPlacards: PropTypes.func,
    customStyles: PropTypes.object,
    title: PropTypes.string
};

export default PlacardsModal;

这是 PDFPlacard.js:

import React from 'react';
import {
    Page,
    Text,
    View,
    Document,
    StyleSheet
} from '@react-pdf/renderer';

// Create styles
const styles = StyleSheet.create({
    page: {
        flexDirection: 'row',
        backgroundColor: '#E4E4E4'
    },
    section: {
        margin: 10,
        padding: 10,
        flexGrow: 1
    }
});

// Create Document Component
const PDFPlacard = (type) => (
    <Document>
        <Page size="letter" style={styles.page}>
            <View style={styles.section}>
                <Text>Section #1</Text>
            </View>
            <View style={styles.section}>
                <Text>Section #2</Text>
            </View>
        </Page>
    </Document>
);

export default PDFPlacard;

还有我的 index.js:

import React from 'react';
import { render } from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min';
import './index.css';
import App from './App';

const title = 'title';

render(<App title={title} />, document.getElementById('root'));

// eslint-disable-next-line no-undef
module.hot.accept();

父母正在像这样加载 PlacardsModal:

...
<button
  className={'btn btn-info mb-3'}
  onClick={() => setOpenPlacards(true)}
>
  Placards
</button>
...
<PlacardsModal
  openPlacards={openPlacards}
  setOpenPlacards={setOpenPlacards}
  customStyles={customStyles}
/>
4

1 回答 1

0

终于从另一个来源得到了答案。我根本不应该打那个ReactDOM.render(电话。我应该在我的页面上包含 PDF 组件。像这样:

...
                <button
                    className={'btn btn-primary d-block mx-auto mb-2'}
                    type={'submit'}
                    value={'Print'}
                />
            </form>
            <!-- not this -->
            <div id={'PDFPlacard'} />
            <!-- this -->
            <PDF />
        </ReactModal>
    );
};
...
于 2019-12-19T19:42:28.523 回答