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

如何修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 10:45:08