You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在React.js中点击不同链接展示对应PDF功能报错如何解决?

问题根因

  • 你报错的原因是首次渲染组件时,DOM还没完成挂载,document.getElementById会返回null,读取null的onToggle属性就触发了类型错误。
  • 你直接操作DOM元素属性判断点击项的逻辑不符合React的状态驱动设计思路,React中不需要通过DOM查询来处理这类交互,完全可以用状态管理来实现。
  • 原组件在没有匹配到任何if条件时没有返回值,会触发组件渲染异常。

解决方法

核心思路是新增状态存储当前选中的文档ID,点击按钮时把对应ID存入状态,再根据状态渲染对应PDF组件即可,修改后的代码如下:

import React, { useState } from "react";
import { Document, Page } from "react-pdf";
import myPdf from '../../../components/pdf/signed.pdf'
import ViewPdf from '../../../components/ViewPdf'
import ViewSecondPdf from '../../../components/ViewPdf2'
import ViewThirdPdf from '../../../components/ViewThirdPdf'
import AllPages from "src/components/pdf/AllPages";
import { Table, Col, Row, Button } from 'reactstrap'
import { Link } from "react-router-dom";

const Display = (props) => {
  return <div>
    <AllPages pdf={props} />
  </div>
}

// PDF组件映射表,后续新增PDF只需要在这里加配置即可
const pdfComponentMap = {
  MICButton: ViewPdf,
  HIButton: ViewSecondPdf,
  CIButton: ViewThirdPdf
}

const DocTable = ({ onToggle }) => {
  return (
    <>
      <Link to="/sign" className="mb-2"><span className="material-icons">keyboard_backspace</span></Link><br />
      <span style={{ fontWeight: 'bold' }}>Documents</span><br />
      <Table bordered hover size="sm">
        <thead>
          <br />
          <tr>
            <th>ID</th>
            <th>Document Name</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">001</th>
            <td><Button id="MICButton" name="MICButton" color="link" onClick={onToggle}>Vehicle Insurance Claim</Button></td>
            <td>Signed</td>
          </tr>
          <tr>
            <th scope="row">002</th>
            <td><Button id="HIButton" name="HIButton" color="link" onClick={onToggle}>Household Insurance Contract</Button></td>
            <td>Signed</td>
          </tr>
          <tr>
            <th scope="row">003</th>
            <td><Button id="CIButton" name="CIButton" color="link" onClick={onToggle}>Vehicle Insurance Contract</Button></td>
            <td>Not Signed</td>
          </tr>
        </tbody>
      </Table>
      <br />
    </>
  );
}

const DocumentList = () => {
  const [isVisible, setIsVisible] = useState(false)
  // 新增状态存储当前选中的文档ID
  const [currentPdfId, setCurrentPdfId] = useState(null)

  const handleToggle = (e) => {
    const clickId = e.target.id
    // 如果点击的是同一个按钮,就切换显示隐藏;如果是新按钮,就更新ID并显示PDF
    if(clickId === currentPdfId) {
      setIsVisible(prev => !prev)
    } else {
      setCurrentPdfId(clickId)
      setIsVisible(true)
    }
  }

  // 拿到当前要渲染的PDF组件
  const CurrentPdfComponent = pdfComponentMap[currentPdfId]

  return (
    <div>
      <Row>
        <Col xs="6">
          <DocTable onToggle={handleToggle} />
        </Col>
        <Col xs="6">
          {isVisible && CurrentPdfComponent && <CurrentPdfComponent />}
        </Col>
      </Row>
    </div>
  )
}
export default DocumentList

优化点说明

  1. 新增currentPdfId状态存储选中的文档ID,完全通过状态驱动渲染,不再操作DOM
  2. 新增PDF组件映射表,避免重复写多段结构相同的渲染逻辑,后续新增PDF只需在映射表中加配置即可
  3. 补充了组件默认返回逻辑,避免无选中状态下的渲染异常
  4. 点击逻辑优化:点击同一个按钮切换显隐,点击不同按钮直接切换展示对应PDF

内容的提问来源于stack exchange,提问作者tanaka98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 20:45:04