在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
优化点说明
- 新增
currentPdfId状态存储选中的文档ID,完全通过状态驱动渲染,不再操作DOM - 新增PDF组件映射表,避免重复写多段结构相同的渲染逻辑,后续新增PDF只需在映射表中加配置即可
- 补充了组件默认返回逻辑,避免无选中状态下的渲染异常
- 点击逻辑优化:点击同一个按钮切换显隐,点击不同按钮直接切换展示对应PDF
内容的提问来源于stack exchange,提问作者tanaka98
相关产品推荐
相关产品推荐

