首页 > 解决方案 > 我们如何从我们正在使用的组件中获取道具?(反应)

问题描述

首先,我没有使用React-Redux. 我知道这会有所帮助,但我的团队需要很长时间才能完成过渡。所以,请理解我需要一个没有React-Redux.

我想要做的是,我正在构建一个 PDF 提取器。我希望用户选择他/她想要提取的 PDF 页面。

我有一个组件叫做PDFViewer渲染工作。

PDF查看器

 renderPdf() {
    const {pdf, pageNo} = this.state
    const container = document.getElementById('container')

    if(this.props.selectedPage){
      console.log('selectedPage exists', this.props.selectedPage)
      pdf.getPage(this.props.selectedPage).then((page) => {
        const scale = this.calcScale(page)
        const viewport = page.getViewport(scale)
        const div = document.createElement('div')

        // Set id attribute with page-#{pdf_page_number} format
        div.setAttribute('id', `page-${(page.pageIndex + 1)}`)
        div.style.width = `${viewport.width}px`
        div.style.height = `${viewport.height}px`
        page
          .getOperatorList()
          .then((opList) => {
            const svgGfx = new window.PDFJS.SVGGraphics(
              page.commonObjs,
              page.objs
            )

            return svgGfx.getSVG(opList, viewport)
          })
          .then((svg) => {
            // If there's already rendered page, delete it.
            if (container.childNodes.length > 0) {
              container.removeChild(container.childNodes[0])
            }
            container.appendChild(svg)
            return svg
          })
      })
    } else {

      console.log('props', this.props)

      pdf.getPage(pageNo).then((page) => {
        const scale = this.calcScale(page)
        const viewport = page.getViewport(scale)
        const div = document.createElement('div')

        // Set id attribute with page-#{pdf_page_number} format
        div.setAttribute('id', `page-${(page.pageIndex + 1)}`)
        div.style.width = `${viewport.width}px`
        div.style.height = `${viewport.height}px`
        page
          .getOperatorList()
          .then((opList) => {
            const svgGfx = new window.PDFJS.SVGGraphics(
              page.commonObjs,
              page.objs
            )

            return svgGfx.getSVG(opList, viewport)
          })
          .then((svg) => {
            // If there's already rendered page, delete it.
            if (container.childNodes.length > 0) {
              container.removeChild(container.childNodes[0])
            }
            container.appendChild(svg)
            return svg
          })
      })
    }
  }

  render() {
    const {pdf, pageNo} = this.state
    const {showPagination} = this.props

    return (
      <div>
        {showPagination && (
          <PageTurner
            nextPage={this.nextPage}
            previousPage={this.previousPage}
            pageNo={pageNo}
            numPages={pdf ? pdf.numPages : 0}
          />
        )}
        <div id="container" />
      </div>
    )

PageTurnerin 渲染只是让用户选择想要渲染的页面。renderPdf()负责渲染它。

下一个组件

render() {
    const tableStyle = this.getTableStyle();
    const tableSettings = this.getTableSettings();
    return (
        <div>
            {//<ReferenceMenu />
            }
            <div 
              style={sideBySide}>
            <PDFViewer
                paginationCallback={this.handlePageChange}
                pdfData={this.state.pdfData}
                desiredWidth={600}
                selectedPage={2}
            />
            <TablePosition
                style={tables}
                step={this.props.step}
                pdfData={this.props.pdfData}
                tableSettings={tableSettings}
                tableStyle={tableStyle}
                fileName={this.state.fileName}
                tableSize={this.getTableSize()}
                tableOffset={this.state.tableOffset}
                desiredWidth={700}
                updateXOffset={x => this.updateXOffset(x)}
                updateYOffset={y => this.updateYOffset(y)}
                markTable={() => this.markTable()}
                setOutputLabels={(row, col, val) => this.setOuputLabels(row, col, val)}
            />
            </div>
        </div>
    );
}

在我的下一个组件中,它尝试呈现所选 PDF 页面的页面并与 PDF 页面具有的表格对齐(表格部分在这个问题中并不重要)。

如您所见,我selectedPage={2}作为道具发送给了PDFViewer,这成功地呈现了 PDF 的第二页。但是该值是硬编码的。

我的问题是,如何获取PDFViewer( this.state.pageNoin PDFViewer) 中选择的页码并在selectedPage={ HERE }?

请帮忙

标签: javascriptreactjs

解决方案


我从评论中获取了我的简单示例,并替换了您的组件名称,以便您更好地了解如何将状态提升到组件树上。我试图将流程建立在我可以从您的问题背景中收集到的内容上。同样,我建议阅读 React 的文章Lifting State Up

const PageTurner = ({ onConfirm, onPageChange, pageNo }) => (
  <div>
    <button type="button" onClick={() => onPageChange(pageNo - 1)}>
      Prev ({pageNo - 1})
    </button>
    <button type="button" onClick={() => onPageChange(pageNo + 1)}>
      Next ({pageNo + 1})
    </button>
    <button type="button" onClick={onConfirm}>
      Confirm
    </button>
  </div>
);

const PdfViewer = ({ pageNo }) => (
  <div>
    <h1>PdfViewer</h1>
    <h2>Current Page is {pageNo}</h2>
  </div>
);

const Step1 = ({ onConfirm, onPageChange, pageNo }) => (
  <div>
    <PdfViewer pageNo={pageNo} />
    <PageTurner
      onConfirm={onConfirm}
      onPageChange={onPageChange}
      pageNo={pageNo}
    />
  </div>
);

const NextComponent = ({ pageNo }) => (
  <div>
    <h1>NextComponent</h1>
    <label>Page number is {pageNo}</label>
  </div>
);
class App extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.state = {
      pageNo: 1,
      step: 1
    };

    this.handleConfirm = this.handleConfirm.bind(this);
    this.handlePageChange = this.handlePageChange.bind(this);
  }

  handleConfirm() {
    this.setState({
      step: 2
    });
  }

  handlePageChange(pageNo) {
    this.setState(state => ({
      pageNo
    }));
  }

  render() {
    const { pageNo, step } = this.state;

    return (
      <div>
        {step === 1 && (
          <Step1
            onConfirm={this.handleConfirm}
            onPageChange={this.handlePageChange}
            pageNo={pageNo}
          />
        )}
        {step === 2 && <NextComponent pageNo={pageNo} />}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>


推荐阅读