SolidJS使用fetch API渲染远程数据时表格数据不显示求助
问题排查与解决方案
核心问题分析
你的问题根源在于jQuery DataTables 与 SolidJS 响应式机制的冲突,以及 DataTables 初始化时机错误:
- 页面刷新时,DataTables 会在
fetch请求加载完成前完成初始化,此时表格数据为空;后续 Signal 更新数据后,DataTables 无法感知 DOM 变化,因此表体始终为空。 - 热更新时,代码保存后页面重新渲染,此时数据可能已缓存或加载完成,DataTables 初始化时能抓取到已存在的 DOM 数据,所以能正常显示。
具体排查与修复步骤
1. 控制 DataTables 初始化时机
使用 SolidJS 的 createEffect 监听 Signal 数据变化,在数据就绪后再初始化/更新 DataTables:
修改 Customers 组件代码:
import { Component, createSignal, createEffect, onCleanup } from 'solid-js'; import Table from '../components/Table'; import $ from "jquery"; // 显式导入jQuery import "datatables.net-bs5"; import { getRequest } from '../utils/utils'; import Customer from '../entities/Customer'; const Customers: Component = () => { const [customers, setCustomers] = createSignal<Customer[]>([]); let tableInstance: DataTables.Api | null = null; // 保存DataTables实例 const columns = [ 'ID Cliente', 'Numero Cliente', 'Azienda?', 'Nome', 'Cognome', 'Sesso', 'Data di nascita', 'Via', 'Città', 'CAP', 'Telefono', 'E-mail' ]; // 发起请求 getRequest("/customers") .then((data) => setCustomers(data)) .catch((e) => window.location.href="/"); // 监听数据变化,初始化/更新DataTables createEffect(() => { const data = customers(); if (data.length > 0 && !tableInstance) { // 初始化DataTables tableInstance = $("#main-table").DataTable(); } else if (tableInstance && data.length > 0) { // 数据更新时重新加载 tableInstance.clear(); tableInstance.rows.add(data.map(row => Object.values(row))); tableInstance.draw(); } }); // 组件卸载时销毁DataTables实例 onCleanup(() => { if (tableInstance) { tableInstance.destroy(); } }); return <> <h2>Clienti</h2> <br /> <Table id="main-table" columns={columns} data={customers()}></Table> </>; } export default Customers;
2. 避免虚拟 DOM 与 DataTables 冲突
DataTables 会直接操纵 DOM,而 SolidJS 通过虚拟 DOM 管理视图,两者可能互相干扰。修改 Table 组件,确保只有当数据存在时才渲染表格:
import { Component, For, Show } from "solid-js"; const Table: Component<{ id: string; columns: string[]; data: any[] }> = ({ id, columns, data, }) => { return ( <div class="table-responsive"> {/* 只有当数据存在时才渲染表格 */} <Show when={data.length > 0}> <table id={id} class="table table-striped table-hovr"> <thead> <For each={columns}>{(col: string) => <th>{col}</th>}</For> </thead> <tbody> <For each={data}> {(row: {}) => ( <tr> <For each={Object.values(row)}> {(d: any) => <td>{d}</td>} </For> </tr> )} </For> </tbody> </table> </Show> </div> ); }; export default Table;
3. 验证 Signal 数据是否正确加载
在 setCustomers 后添加日志,确认数据是否正确获取:
getRequest("/customers") .then((data) => { console.log("Loaded customers:", data); // 查看控制台输出 setCustomers(data); }) .catch((e) => { console.error("Request error:", e); window.location.href="/"; });
如果控制台没有数据,说明 getRequest 可能存在问题,比如 config.api_url 或 config.jwt 未正确配置,需要检查接口地址和授权头。
额外注意事项
- 避免同时依赖 jQuery 和 SolidJS 管理同一 DOM 元素,尽量保持视图控制单一化。
- 如果不需要 DataTables 的高级功能,可考虑使用纯 SolidJS 的表格组件(如
solid-table),彻底避免框架冲突。
内容的提问来源于stack exchange,提问作者Niccolò Cavallini
相关产品推荐
相关产品推荐

