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

如何从React Router Loader Hook获取数据并传入Gantt组件

如何通过React Router Loader将动态数据传入Syncfusion React Gantt图表

你可以直接在GanttChart函数组件内处理从Loader获取到的数据,将其转换为Gantt组件要求的格式,替换原有的静态GanttData。具体实现如下:

修改步骤

  1. 删除静态定义的GanttData常量,改为动态生成
  2. 在组件内编写数据转换函数,将接口返回的projects映射为Gantt所需的结构
  3. 将转换后的动态数据传入GanttComponent的dataSource属性

完整修改代码

export const loader = async ({ request, params }) => {
  try {
    const { data } = await customFetch.get(`/projects`);
    return data;
  } catch (error) {
    toast.error(error?.response?.data?.msg);
    return redirect("/dashboard/all-jobs");
  }
};

const splitterSettings = {
  position: "30%",
};

const timelineSettings = {
  timelineUnitSize: 60,
  timelineViewMode: "Month",
  topTier: {
    unit: "Year",
  },
  bottomTier: {
    unit: "Month",
  },
};

// 转换接口数据为Gantt要求的结构
const convertToGanttFormat = (projects) => {
  return projects.map((project, idx) => {
    // 这里根据你的接口返回字段调整映射关系
    const baseId = idx + 1;
    return {
      TaskID: baseId,
      ProjectNo: project.projectNo,
      TaskName: project.name,
      StartDate: new Date(project.startDate),
      EndDate: new Date(project.endDate),
      subtasks: [
        {
          TaskID: parseFloat(`${baseId}.1`),
          TaskName: "Sodium Carbonate",
          StartDate: new Date(project.startDate),
          Duration: 4,
          Progress: 150,
          comments: "unlucky",
          subtasks: [
            {
              TaskID: parseFloat(`${baseId}.11`),
              TaskName: "Design",
              StartDate: new Date(project.startDate),
              Duration: 30,
              Progress: 150,
            },
            {
              TaskID: parseFloat(`${baseId}.12`),
              TaskName: "Workshop",
              StartDate: new Date(project.startDate.setMonth(project.startDate.getMonth() + 1)),
              Duration: 30,
              Progress: 150,
            },
            {
              TaskID: parseFloat(`${baseId}.13`),
              TaskName: "Site",
              StartDate: new Date(project.startDate.setMonth(project.startDate.getMonth() + 2)),
              Duration: 30,
              Progress: 150,
            },
          ],
        },
        {
          TaskID: parseFloat(`${baseId}.2`),
          TaskName: "PACl",
          StartDate: new Date(project.startDate),
          Duration: 4,
          Progress: 150,
          comments: "unlucky",
          subtasks: [
            {
              TaskID: parseFloat(`${baseId}.21`),
              TaskName: "Design",
              StartDate: new Date(project.startDate),
              Duration: 30,
              Progress: 150,
            },
            {
              TaskID: parseFloat(`${baseId}.22`),
              TaskName: "Workshop",
              StartDate: new Date(project.startDate.setMonth(project.startDate.getMonth() + 1)),
              Duration: 30,
              Progress: 150,
            },
            {
              TaskID: parseFloat(`${baseId}.23`),
              TaskName: "Site",
              StartDate: new Date(project.startDate.setMonth(project.startDate.getMonth() + 2)),
              Duration: 30,
              Progress: 150,
            },
          ],
        }
      ]
    };
  });
};

function GanttChart() {
  const { projects } = useLoaderData();
  // 生成动态Gantt数据源
  const dynamicGanttData = convertToGanttFormat(projects);

  const taskFields = {
    id: "TaskID",
    name: "TaskName",
    startDate: "StartDate",
    duration: "Duration",
    progress: "Progress",
    child: "subtasks",
  };
  return (
    <GanttComponent
      dataSource={dynamicGanttData}
      taskFields={taskFields}
      height="530px"
      width="1200px"
      splitterSettings={splitterSettings}
      allowResizing={false}
      timelineSettings={timelineSettings}
      collapseAllParentTasks={true}
    >
      <ColumnsDirective maxWidth="100" minWidth="70" width="10">
        <ColumnDirective
          field="TaskID"
          width="100"
          maxWidth="100"
          minWidth="100"
        ></ColumnDirective>
        <ColumnDirective
          field="ProjectNo"
          headerText="Project Number"
          width="80"
          allowResizing={false}
          maxWidth="100"
          minWidth="100"
        ></ColumnDirective>
        <ColumnDirective
          field="TaskName"
          headerText="Task Name"
          width="200"
          maxWidth="100"
          minWidth="100"
        ></ColumnDirective>
      </ColumnsDirective>
      <Inject services={[Resize]} />
    </GanttComponent>
  );
}

export default GanttChart;

关键说明

  • 字段映射:convertToGanttFormat函数中,需要根据你的实际接口返回字段调整映射关系,比如project.projectNo对应Gantt的ProjectNo,确保日期字符串转换为Date对象。
  • TaskID唯一性:通过索引生成层级化的唯一ID,你也可以改用项目自身的ID来构建。
  • 子任务逻辑:如果你的接口返回项目包含自有子任务数据,可以直接从project.subtasks映射,否则沿用原静态模板结构即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:07:34