如何修改useRef克隆的表格数据,使其展示预设文本而非用户输入内容
问题根源
- 执行顺序错误:预设文本替换逻辑放在组件主渲染流程,表格克隆操作在useEffect回调中执行。React状态变更后会先跑完组件主逻辑,再执行useEffect,导致你先替换了克隆表格内容,后续克隆操作直接用原表格带用户输入的内容覆盖了克隆表格,替换逻辑失效。
- 缺少边界判断:未判断ref是否存在,首次渲染时可能出现空指针报错。
修复方案
把预设文本替换逻辑移到克隆操作之后执行,保证替换后的内容不会被克隆操作覆盖。
修改后完整代码
import React, { useState, useEffect, useRef } from "react"; export default function App() { const tableRef = useRef(null); const clonedTableRef = useRef(null); const [disclaimer, setDisclaimer] = useState(); const [signoff, setSignOff] = useState(); useEffect(() => { handleCopyTable(); }, [disclaimer, signoff]); const handleCopyTable = () => { // 增加边界判断避免空指针报错 if (!tableRef.current || !clonedTableRef.current) return; // 先克隆原表格内容 clonedTableRef.current.innerHTML = tableRef.current.innerHTML; // 克隆完成后立刻替换对应位置为预设文本 if (disclaimer) { clonedTableRef.current.querySelector("#disclaimer").innerText = "Predifined Text for disclaimer"; } if (signoff) { clonedTableRef.current.querySelector("#signoff").innerText = "Predifined Text for signoff"; } }; return ( <div className="App"> <div className="disclaimer-box"> <textarea placeholder="Type your characters here" onChange={(e) => setDisclaimer(e.target.value)} rows="3" cols="30" ></textarea> <button>Add Disclaimer</button> </div> <div className="signoff-box"> <textarea placeholder="Type your characters here" onChange={(e) => setSignOff(e.target.value)} rows="3" cols="30" ></textarea> <button>Add signoff</button> </div> <h1>Original table </h1> <div ref={tableRef} className="table"> <table width="500" cellPadding="0" cellSpacing="0" border="0"> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr style={{ fontSize: "8px", fontFamily: "Verdana", color: "#fff", lineHeight: "10px", paddingTop: "10px", backgroundColor: "red" }} > <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> <td>Mark</td> <td>Otto</td> </tr> <tr style={{ margin: "20px" }}> <td id="disclaimer" style={{ padding: "20px" }}> Disclaimer : {disclaimer}{" "} </td> <td id="signoff" style={{ padding: "20px" }}> signoff : {signoff}{" "} </td> </tr> </tbody> </table> </div> <h1>Cloned Table</h1> <div ref={clonedTableRef} className="table"></div> </div> ); }
内容的提问来源于stack exchange,提问作者The Dead Man
相关产品推荐
相关产品推荐

