please see my code below. I am currently trying to create a gantt chart using syncfusion react gantt charts. The code works fine as is but I now want to change the data in the GanttData array which is the data source for the GanttComponent so that it is dynamic. I am using react router dom to pull in data from a database using the loader hook. Once I get this data I want to pull out some dates and put them in the GanttData array but I don't know how as I can't use useLoaderData unless it is in a function. Can anyone assist? Apologies if this isn't clear. Please let me know if you need more information.
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 GanttData = [
{
TaskID: 1,
ProjectNo: "29895",
TaskName: "Stoneybridge WTW",
StartDate: new Date("04/02/2019"),
EndDate: new Date("05/21/2019"),
subtasks: [
{
TaskID: 1.1,
TaskName: "Sodium Carbonate",
StartDate: new Date("04/02/2019"),
Duration: 4,
Progress: 150,
comments: "unlucky",
subtasks: [
{
TaskID: 1.11,
TaskName: "Design",
StartDate: new Date("04/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 1.12,
TaskName: "Workshop",
StartDate: new Date("05/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 1.13,
TaskName: "Site",
StartDate: new Date("06/02/2019"),
Duration: 30,
Progress: 150,
},
],
},
{
TaskID: 1.2,
TaskName: "PACl",
StartDate: new Date("04/02/2019"),
Duration: 4,
Progress: 150,
comments: "unlucky",
subtasks: [
{
TaskID: 1.21,
TaskName: "Design",
StartDate: new Date("04/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 1.22,
TaskName: "Workshop",
StartDate: new Date("05/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 1.23,
TaskName: "Site",
StartDate: new Date("06/02/2019"),
Duration: 30,
Progress: 150,
},
],
},
{
TaskID: 1.3,
TaskName: "Ammonium Sulphate",
StartDate: new Date("04/02/2019"),
Duration: 4,
Progress: 150,
comments: "unlucky",
subtasks: [
{
TaskID: 1.31,
TaskName: "Design",
StartDate: new Date("04/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 1.2,
TaskName: "Workshop",
StartDate: new Date("05/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 1.13,
TaskName: "Site",
StartDate: new Date("06/02/2019"),
Duration: 30,
Progress: 150,
},
],
},
],
},
{
TaskID: 2,
ProjectNo: "31139",
TaskName: "Barra WTW",
StartDate: new Date("04/02/2019"),
EndDate: new Date("05/21/2019"),
subtasks: [
{
TaskID: 2.1,
TaskName: "Sodium Carbonate",
StartDate: new Date("04/02/2019"),
Duration: 4,
Progress: 150,
comments: "unlucky",
subtasks: [
{
TaskID: 2.11,
TaskName: "Design",
StartDate: new Date("04/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 2.12,
TaskName: "Workshop",
StartDate: new Date("05/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 2.13,
TaskName: "Site",
StartDate: new Date("06/02/2019"),
Duration: 30,
Progress: 150,
},
],
},
{
TaskID: 2.2,
TaskName: "Ammonium Sulphate",
StartDate: new Date("04/02/2019"),
Duration: 4,
Progress: 150,
comments: "unlucky",
subtasks: [
{
TaskID: 2.21,
TaskName: "Design",
StartDate: new Date("04/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 2.22,
TaskName: "Workshop",
StartDate: new Date("05/02/2019"),
Duration: 30,
Progress: 150,
},
{
TaskID: 2.23,
TaskName: "Site",
StartDate: new Date("06/02/2019"),
Duration: 30,
Progress: 150,
},
],
},
],
},
];
const splitterSettings = {
position: "30%",
};
const timelineSettings = {
timelineUnitSize: 60,
timelineViewMode: "Month",
topTier: {
unit: "Year",
},
bottomTier: {
unit: "Month",
},
};
function GanttChart() {
const { projects } = useLoaderData();
console.log(projects);
console.log(projects[0].projectEnd);
const taskFields = {
id: "TaskID",
name: "TaskName",
startDate: "StartDate",
duration: "Duration",
progress: "Progress",
child: "subtasks",
};
return (
<GanttComponent
dataSource={GanttData}
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;
The problem you have is that GanttData
is a standard JS variable so that each time your component (a JS function) gets rendered (i.e. "run the function"), then the variable GanttData
is recreated and re-initialized with the hard coded values you have provided it.
If you want to have a variable that holds data, be able to update that data and see that changed data across renders, then you want to use a state variable (useState()
) or a reference variable (useRef()
). The benefit of a state variable is that when you update the value with the "set state function" then the component that has that state variable (the component that calls useState()
) will cause the component to be re-rendered. The benefit of reference variables is that you can update their value while not causing the component to re-render.
So in your case I suspect you want to define GanttData
(which I would recommend to rename as ganttData
) as a state variable (const [ganttData, setGanttData] = useState([{ ...... }])
) and then in your loader()
function update the state variable using setGanttData()
to put the newly fetched values into ganttData
, which will then cause the component to re-render showing you the newly obtained values.