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

Next.js中Axios获取数据无法在TanStack Table展示的问题

问题:Next.js中Axios获取的数据无法在TanStack Table中展示
  • 在ProjectsTableBlock组件的help1与help2之间能正常打印Axios获取到的数据
  • 但数据无法在Table组件的dell1与dell2之间打印,也无法在表格HTML中展示
  • 硬编码数据测试时,TanStack Table功能完全正常

相关代码

ProjectsTableBlock.tsx

import React, { ReactNode, useEffect } from "react";
import Block from "./Block";
import Button from "../Button";
import Table from "../Table";

import { createColumnHelper } from "@tanstack/react-table";
import axios from "axios";

type ProjectsTableBlockProps = {
    block_span: string;
    children: ReactNode;
};

type Project = {
    project_id: number;
    name: string;
    description: string;
    organization_id: number;
};

const columnHelper = createColumnHelper<Project>();

const columns = [
    columnHelper.accessor("project_id", {
        header: () => "Project ID",
        cell: (info) => info.getValue(),
        footer: (info) => info.column.id,
    }),
    columnHelper.accessor("name", {
        cell: (info) => <i>{info.getValue()}</i>,
        header: () => "Name",
        footer: (info) => info.column.id,
    }),
    columnHelper.accessor("description", {
        header: "Description",
        cell: (info) => info.getValue(),
        footer: (info) => info.column.id,
    }),
    columnHelper.accessor("organization_id", {
        header: "Organization ID",
        cell: (info) => info.getValue(),
        footer: (info) => info.column.id,
    }),
];

export default function ProjectsTableBlock(ProjectsTableBlockProps) {
    const [data, setData] = React.useState<Project[]>([]);

    useEffect(() => {
        axios
            .get("/api/projects")
            .then((response) => {
                setData(response.data);
            })
            .catch((error) => console.error("Error fetching projects:", error));
    }, []);

    console.log("help1");
    console.log(data);
    console.log("help2");

    return (
        <Block>
            <div className=" flex items-center justify-between pb-6">
                <div>
                    <h2 className="text-gray-600 font-semibold">Projects</h2>
                    <span className="text-xs">Projects List</span>
                </div>
                <div className="flex items-center justify-between">
                    <div className="lg:ml-40 ml-10 space-x-8">
                        <Button action="Create">Create</Button>
                    </div>
                </div>
            </div>
            <div>
                <div className="-mx-4 sm:-mx-8 px-4 sm:px-8 py-4 overflow-x-auto">
                    <div className="inline-block min-w-full shadow rounded-lg overflow-hidden">
                        <Table columns={columns} data={data}></Table>
                    </div>
                </div>
            </div>
        </Block>
    );
}

Table.tsx

import { ViewColumnsIcon } from "@heroicons/react/24/outline";
import React, { useState } from "react";

import {
    createColumnHelper,
    flexRender,
    getCoreRowModel,
    useReactTable,
} from "@tanstack/react-table";

type TableProps = {
    columns: any;
    data: any;
};

export default function Table(TableProps) {
    const [data, setData] = React.useState(() => [...TableProps.data]);

    const table = useReactTable({
        data,
        columns: TableProps.columns,
        getCoreRowModel: getCoreRowModel(),
    });

    console.log("dell1");
    console.log(data);
    console.log("dell2");

    return (
        <div>
            <table className="min-w-full">
                <thead className="bg-white border-b">
                    {table.getHeaderGroups().map((headerGroup) => (
                        <tr key={headerGroup.id}>
                            {headerGroup.headers.map((header) => (
                                <th key={header.id}>
                                    {header.isPlaceholder
                                        ? null
                                        : flexRender(
                                              header.column.columnDef.header,
                                              header.getContext()
                                          )}
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody>
                    {table.getRowModel().rows.map((row) => (
                        <tr className="bg-white border-b" key={row.id}>
                            {row.getVisibleCells().map((cell) => (
                                <td
                                    className="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap"
                                    key={cell.id}
                                >
                                    {flexRender(
                                        cell.column.columnDef.cell,
                                        cell.getContext()
                                    )}
                                </td>
                            ))}
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
}

解决方案

问题出在Table组件的内部状态逻辑:

  1. 问题根源:Table组件用useState初始化了内部data状态,初始值是[...TableProps.data]。但这个初始化仅在组件首次挂载时执行一次,当父组件ProjectsTableBlock通过Axios获取到新数据并更新data后,子组件Table的内部状态不会同步更新——因为useState的初始值不会随props变化而重新计算。

  2. 修复方法:直接移除Table组件内部的data状态,直接使用props传入的数据即可,无需额外维护内部状态。

修复后的Table.tsx

import { ViewColumnsIcon } from "@heroicons/react/24/outline";
import React from "react";

import {
    flexRender,
    getCoreRowModel,
    useReactTable,
} from "@tanstack/react-table";

type TableProps = {
    columns: any;
    data: any;
};

export default function Table({ columns, data }: TableProps) {
    const table = useReactTable({
        data,
        columns,
        getCoreRowModel: getCoreRowModel(),
    });

    console.log("dell1");
    console.log(data);
    console.log("dell2");

    return (
        <div>
            <table className="min-w-full">
                <thead className="bg-white border-b">
                    {table.getHeaderGroups().map((headerGroup) => (
                        <tr key={headerGroup.id}>
                            {headerGroup.headers.map((header) => (
                                <th key={header.id}>
                                    {header.isPlaceholder
                                        ? null
                                        : flexRender(
                                              header.column.columnDef.header,
                                              header.getContext()
                                          )}
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody>
                    {table.getRowModel().rows.map((row) => (
                        <tr className="bg-white border-b" key={row.id}>
                            {row.getVisibleCells().map((cell) => (
                                <td
                                    className="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap"
                                    key={cell.id}
                                >
                                    {flexRender(
                                        cell.column.columnDef.cell,
                                        cell.getContext()
                                    )}
                                </td>
                            ))}
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
}

说明

  • 直接使用props传入的data,当父组件更新数据时,子组件会自动重新渲染,TanStack Table也会同步使用最新数据生成表格
  • 移除不必要的内部状态后,组件逻辑更简洁,数据流向更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:52:54