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

React项目部署JBOSS JWS后,用navigate实现表格跳转失效求助

解决方案

核心问题在于你混用了原生DOM操作和React组件体系,同时违反了React Hook的使用规则。以下是正确的实现方案:

1. 修正Hook使用规则

useNavigate必须在函数组件的顶层作用域调用,不能在普通函数(比如loadTableDataNotification)内部调用。在Main组件顶层定义navigate:

function Main() {
  const navigate = useNavigate(); // 移到组件顶层
  // ...其他state和函数
}

2. 放弃原生DOM构建表格,改用React JSX渲染

原生DOM操作(insertRow/insertCell)会脱离React的虚拟DOM管控,导致React Router的导航无法正常工作。改用React状态管理表格数据,通过JSX渲染表格内容。

重构核心思路:

  • 用状态存储当前分页的表格结构化数据
  • 删除原生DOM操作逻辑,通过React的map方法渲染表格行
  • 用Link组件或Button+navigate实现跳转

3. 修改后的完整代码

import React, { useEffect, useState } from "react";
import axios from 'axios';
import { Routes, Route, Link, useNavigate } from 'react-router-dom';
import ViewQuery from "./ViewQuery";
import ReactPaginate from "react-paginate"; // 确保已安装该依赖

function Main() {
  const navigate = useNavigate(); // 正确在组件顶层调用Hook
  const [currentItems, setCurrentItems] = useState([]);
  const [pageCount, setPageCount] = useState(0);
  const [itemOffset, setItemOffset] = useState(0);
  const itemsPerPage = 10; // 可根据需求调整
  
  // 替换为实际业务变量
  const type = "";
  const id = "";
  const username = "";

  useEffect(() => {
    const urlString = `${window.globalURL}getEagleEyeRequestDataNotification/${type}/${id}`;
    axios.get(urlString)
      .then(response => {
        // 整理成结构化数据,避免字符串拼接
        const tableData = response.data.map(item => ({
          requestId: item.request_id,
          description: item.description
        }));
        const endOffset = itemOffset + itemsPerPage;
        setCurrentItems(tableData.slice(itemOffset, endOffset));
        setPageCount(Math.ceil(tableData.length / itemsPerPage));
      });
  }, [itemOffset, itemsPerPage, type, id]);

  const handlePageClick = (event) => {
    const newOffset = event.selected * itemsPerPage;
    setItemOffset(newOffset);
  };

  // 自定义跳转函数,用于Button场景
  const goToDetail = (requestId) => {
    navigate(`/ViewQuery?request_id=${requestId}&id=${id}&name=${username}&type=${type}`);
  };

  return (
    <div id='myApp' style={{ margin: "10px" }}>
      <Routes>
        <Route path="ViewQuery" element={<ViewQuery />} />
      </Routes>

      <table style={{ padding: 0 }}>
        <tr>
          <td style={{ backgroundColor: "#b6e4fe", color: "white", width: "8%" }}></td>
          <td>
            <br />
            <table style={{ width: '100%', borderTop: '1px solid grey', borderBottom: '1px solid grey', textAlign: 'left', fontFamily: 'Calibri', fontSize: '18px', color: 'grey', fontWeight: 'bold' }}>
              <tr><td>NOTIFICATION</td></tr>
            </table>

            {/* React方式渲染表格 */}
            <table id="tableNotification" cellspacing="5" cellpadding="5">
              <thead>
                <tr style={{ fontSize: '12px', color: 'grey', fontWeight: 'bold' }}>
                  <td>Req ID</td>
                  <td>Description</td>
                </tr>
              </thead>
              <tbody>
                {currentItems.map(item => (
                  <tr key={item.requestId} style={{ fontSize: "12px", color: "grey" }}>
                    {/* 方案1:用Link组件(推荐,符合React Router规范) */}
                    <td>
                      <Link 
                        to={`/ViewQuery?request_id=${item.requestId}&id=${id}&name=${username}&type=${type}`}
                        style={{ textDecoration: 'none', color: 'blue' }}
                      >
                        {item.requestId}
                      </Link>
                    </td>
                    {/* 方案2:用Button+navigate(适合需要自定义样式的场景) */}
                    {/* <td>
                      <button 
                        onClick={() => goToDetail(item.requestId)}
                        style={{ border: 'none', background: 'none', color: 'blue', cursor: 'pointer', textDecoration: 'underline' }}
                      >
                        {item.requestId}
                      </button>
                    </td> */}
                    <td>{item.description}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            {/* 分页组件 */}
            <ReactPaginate
              nextLabel="next >"
              onPageChange={handlePageClick}
              pageRangeDisplayed={3}
              marginPagesDisplayed={2}
              pageCount={pageCount}
              previousLabel="< previous"
              pageClassName="page-item"
              pageLinkClassName="page-link"
              previousClassName="page-item"
              previousLinkClassName="page-link"
              nextClassName="page-item"
              nextLinkClassName="page-link"
              breakLabel="..."
              breakClassName="page-item"
              breakLinkClassName="page-link"
              containerClassName="pagination"
              activeClassName="active"
              renderOnZeroPageCount={null}
            />
          </td>
        </tr>
      </table>
    </div>
  );
}

export default Main;

关键说明

  • 原生a标签失效原因:部署到JWS后应用可能存在基路径差异,原生a标签的相对路径无法适配客户端路由,而React Router的Link会自动处理路由基路径,确保跳转正确。
  • Hook规则约束:所有React Hook必须在组件顶层调用,不能在嵌套函数、循环或条件语句中使用,否则会触发无效Hook调用错误。
  • innerHTML的限制:innerHTML只能解析普通HTML元素,无法识别React组件(如Button、Link),必须用JSX方式渲染React组件才能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:57:51