Just dummy data should do hopefully (similar to how our demos are structured). Without being able to run code, it's hard for us to assist.
Support Forum
I managed to scale down our class in order to showcase the problem. It seems that whenever it re-renders the whole UI breaks down.
The class is as follows:
/* eslint-disable */
import React, { Component } from "react";
import classNames from "classnames";
import styled from "styled-components";
import { diff } from "deep-object-diff";
import "components/common/Scheduler/Scheduler.styles.scss";
import { zoomLevelMapping } from "config/zoomConfig";
import { BryntumScheduler } from "@bryntum/scheduler-react";
const SchedulerContainer = styled.div`
grid-column: 1 / 2;
grid-row: 2;
overflow: hidden;
padding: 10px 0 0 0;
`;
export default class OldBryntumScheduler extends Component {
constructor(props) {
super(props);
this.schedulerRef = React.createRef();
}
componentDidMount() {
const { onBryntumInitialized, zoomLevel, startDate, endDate } = this.props;
this.schedulerInstance = this.schedulerRef.current?.instance;
onBryntumInitialized(this.schedulerInstance);
this.resetScheduleTimeRange({ centerDate: new Date(), zoomLevel, startDate, endDate });
}
shouldComponentUpdate(nextProps) {
const updatedProps = Object.keys(diff(nextProps, this.props));
if (updatedProps.includes("events")) return true;
if (updatedProps.includes("shiftInstances")) return true;
return false;
}
resetScheduleTimeRange({ centerDate, zoomLevel, startDate, endDate }) {
this.schedulerInstance.zoomTo({
...zoomLevelMapping(zoomLevel),
startDate,
centerDate: centerDate || this.schedulerInstance.viewportCenterDate,
endDate,
});
}
render() {
return (
<SchedulerContainer className={classNames("spec-schedule", "b-react-scheduler-container")} id="bryntum-scheduler">
<BryntumScheduler
ref={this.schedulerRef}
{...this.props.config}
events={this.props.events}
timeRanges={this.props.shiftInstances}
/>
</SchedulerContainer>
);
}
}
I am working on trying to adapt a demo to see if I can reproduce but maybe something is obvious in the above code? If componentShouldUpdate
returns false, any edits I make work but additions and removals do not work.
I also attempted to use hooks instead of sending the data in. In this code sample it rendered but the dates and times just flashed once and then disappeared. The first edit i made to an event was fine, the second one broke the entire UI again
import React, { useEffect, useRef } from "react";
import classNames from "classnames";
import styled from "styled-components";
import "components/common/Scheduler/Scheduler.styles.scss";
import { zoomLevelMapping } from "config/zoomConfig";
import { BryntumScheduler } from "@bryntum/scheduler-react";
const SchedulerContainer = styled.div`
grid-column: 1 / 2;
grid-row: 2;
overflow: hidden;
padding: 10px 0 0 0;
`;
export default function OldBryntumScheduler({
config,
events,
shiftInstances,
zoomLevel,
startDate,
endDate
}) {
const schedulerRef = useRef();
useEffect(() => {
const schedulerInstance = schedulerRef.current?.instance;
schedulerInstance.events = events;
}, [events]);
useEffect(() => {
const schedulerInstance = schedulerRef.current?.instance;
schedulerInstance.timeRanges = shiftInstances;
}, [shiftInstances]);
useEffect(() => {
const schedulerInstance = schedulerRef.current?.instance;
resetScheduleTimeRange({ schedulerInstance, centerDate: new Date() });
}, [zoomLevel, startDate, endDate]);
const resetScheduleTimeRange = ({ schedulerInstance, centerDate }) => {
schedulerInstance.zoomTo({
...zoomLevelMapping(zoomLevel),
startDate,
centerDate: centerDate || schedulerInstance.viewportCenterDate,
endDate,
});
};
return (
<SchedulerContainer className={classNames("spec-schedule", "b-react-scheduler-container")} id="bryntum-scheduler">
<BryntumScheduler ref={schedulerRef} {...config} />
</SchedulerContainer>
);
}
I also tried to not just set events but call addEvent
and removeEvent
where needed but it made no difference.
Ill work on trying to break the demo in the same way
Hi jasony,
import classNames from "classnames";
import styled from "styled-components";
import "components/common/Scheduler/Scheduler.styles.scss";
import { zoomLevelMapping } from "config/zoomConfig";
Please zip the whole app and attach here, included package.json (and CSS classes you mentioned in the code) to manage dependencies you used in the code, so we will be able to run the code with the data you used.
All the best,
Alex
Here is a sample of the data
[
{
"resourceId": "238227c1-70a8-4f1d-bf01-cd44ae94407b",
"id": "947dde53-ffba-4f0b-98c3-48bb1bcadea8",
"startDate": "2023-01-04T16:15:00.000Z",
"endDate": "2023-01-04T18:35:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "238227c1-70a8-4f1d-bf01-cd44ae94407b",
"id": "8bbced3d-8d67-4c84-a5a2-aa89f8a45d44",
"startDate": "2023-01-04T22:05:00.000Z",
"endDate": "2023-01-05T00:40:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "a37ebf28-a590-40fe-86d0-6ff4fb97541e",
"id": "f63f3653-d0c4-402a-b6f3-9b3d60b3739f",
"startDate": "2023-01-04T13:00:00.000Z",
"endDate": "2023-01-04T19:35:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "d3eed3ba-9521-4190-b849-5ac82f8f1cc4",
"id": "ac514ec5-4f3c-47ff-8e66-f313c865fb66",
"startDate": "2023-01-05T09:50:00.000Z",
"endDate": "2023-01-05T17:50:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "d3eed3ba-9521-4190-b849-5ac82f8f1cc4",
"id": "145c4a3d-7186-42b3-b4b4-6d3018630f35",
"startDate": "2023-01-05T17:50:00.000Z",
"endDate": "2023-01-05T21:50:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "d3eed3ba-9521-4190-b849-5ac82f8f1cc4",
"id": "70997653-87da-4e9f-a1c0-2ebf75c19b11",
"startDate": "2023-01-05T21:50:00.000Z",
"endDate": "2023-01-06T05:50:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "d3eed3ba-9521-4190-b849-5ac82f8f1cc4",
"id": "cfb41371-1364-40e2-a998-788fb3a448c2",
"startDate": "2023-01-04T02:00:00.000Z",
"endDate": "2023-01-04T06:00:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "d3eed3ba-9521-4190-b849-5ac82f8f1cc4",
"id": "f2a08d73-38f2-4d6c-bf57-a01241cab19f",
"startDate": "2023-01-04T06:00:00.000Z",
"endDate": "2023-01-04T07:45:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
},
{
"resourceId": "d3eed3ba-9521-4190-b849-5ac82f8f1cc4",
"id": "32f4d224-2502-4426-9ed9-3f65ee3c7ea3",
"startDate": "2023-01-04T07:45:00.000Z",
"endDate": "2023-01-04T11:45:00.000Z",
"draggable": true,
"resizable": true,
"eventStyle": "null"
}
]
When a block gets changed/moved/created/deleted we post to a graphql backend and the backend fires subscriptions which we respond to. When we get the subscription, we update the Apollo cache and that in turns triggers the events
we send in to change and causes a rerender.
Hi jasony,
I checked the code and data provided. I applied all meaningful changes from your code snippets to our React example but was not able to reproduce the issue.
We need your further assistance here.
Please find "react-state" demo in /examples/frameworks/react/javascript folder and review the code. This should be a good point to start since it uses same approach as you described here. Try to apply required changes to that demo to reproduce the problem.
Please check if any warnings appeared in console before the error you posted here. It might be a warning about change properties that are not allowed to be changed at runtime. If so, then approach in react-state will definitely help you.
All the best,
Alex
We were unable to break the demo so far but we tried to put the demo code inside our app and got it down to the following:
/**
* The App component
*/
import React, { useState, useRef, useCallback } from "react";
import "components/common/Scheduler/Scheduler.styles.scss";
import { Toast } from "@bryntum/scheduler";
import { BryntumScheduler } from "@bryntum/scheduler-react";
const BryntumSchedulerWrapper = () => {
const initialIndex = 0;
const schedulerRef = useRef(null);
const theEvents = [
{
id: 1,
resourceId: "r1",
startDate: new Date(2021, 8, 3, 10),
endDate: new Date(2021, 8, 3, 12),
name: "Click me (dataset 0)",
iconCls: "b-fa b-fa-mouse-pointer",
},
{
id: 2,
resourceId: "r2",
startDate: new Date(2021, 8, 3, 12),
endDate: new Date(2021, 8, 3, 13, 30),
name: "Drag me",
iconCls: "b-fa b-fa-arrows-alt",
},
{
id: 3,
resourceId: "r3",
startDate: new Date(2021, 8, 3, 14),
duration: 2,
durationUnit: "h",
name: "Double click me",
eventColor: "purple",
iconCls: "b-fa b-fa-mouse-pointer",
},
{
id: 4,
resourceId: "r4",
startDate: new Date(2021, 8, 3, 8),
endDate: new Date(2021, 8, 3, 11),
name: "Right click me",
iconCls: "b-fa b-fa-mouse-pointer",
},
{
id: 5,
resourceId: "r5",
startDate: new Date(2021, 8, 3, 15),
endDate: new Date(2021, 8, 3, 17),
name: "Resize me",
iconCls: "b-fa b-fa-arrows-alt-h",
},
{
id: 6,
resourceId: "r6",
startDate: new Date(2021, 8, 3, 16),
endDate: new Date(2021, 8, 3, 19),
name: "Important meeting",
iconCls: "b-fa b-fa-exclamation-triangle",
eventColor: "red",
},
{
id: 7,
resourceId: "r6",
startDate: new Date(2021, 8, 3, 6),
endDate: new Date(2021, 8, 3, 8),
name: "Sports event",
iconCls: "b-fa b-fa-basketball-ball",
},
{
id: 8,
resourceId: "r7",
startDate: new Date(2021, 8, 3, 9),
endDate: new Date(2021, 8, 3, 11, 30),
name: "Dad's birthday!",
iconCls: "b-fa b-fa-birthday-cake",
// Custom styling from data
style: "background-color : teal; font-size: 18px",
// Prevent default styling
eventStyle: "none",
},
];
const theResources = [
{ id: "r1", name: "Mike" },
{ id: "r2", name: "Linda" },
{ id: "r3", name: "Chang" },
{ id: "r4", name: "Kate" },
{ id: "r5", name: "Lisa" },
{ id: "r6", name: "Steve" },
{ id: "r7", name: "Mark" },
{ id: "r8", name: "Madison" },
{ id: "r9", name: "Hitomi" },
{ id: "r10", name: "Dan" },
];
const [index, setIndex] = useState(initialIndex);
const [resources, setResources] = useState(theResources);
const [events, setEvents] = useState(theEvents);
// Called when data changes in any of the Scheduler stores
const onDataChange = useCallback(({ store, action, records }) => {
if ("dataset" !== action && store.changes) {
Toast.show(`
<h3>${store.storeId} changed</h3>
Added: <strong>${store.changes.added.length}</strong>
Modified: <strong>${store.changes.modified.length}</strong>
Removed: <strong>${store.changes.removed.length}</strong>
`);
}
}, []);
const schedulerConfig = {
viewPreset: "hourAndDay",
startDate: new Date(2021, 8, 3, 6),
endDate: new Date(2021, 8, 3, 20),
resourceImagePath: "users/",
eventStore: {
syncDataOnLoad: true,
},
columns: [{ type: "resourceInfo", text: "Staff", field: "name" }],
};
return (
<>
<BryntumScheduler
{...schedulerConfig}
events={events}
resources={resources}
ref={schedulerRef}
onDataChange={onDataChange}
/>
</>
);
};
export default BryntumSchedulerWrapper;
We do not send in any props or anything else from our app. However if the parent component re-renders causing a rerender in this component all the events disappear. I attach a video of this to this message.
We attempted to reproduce it in the demo app but for some reason we were unable to reproduce it when re-rendering in that app.
In the attached video you will see there are some warnings that appear at the start but the app still works. As soon as we change the date (we ripped out all the code so it just rerenders the component but doesn't change the actual dates), the event disappear and everytime we try to use the scheduler we get those errors. You can ignore the popper error that showed up, that is related to the date dropdown
- Attachments
-
- Screen Recording 2023-01-06 at 13.49.30.mov
- (12.43 MiB) Downloaded 23 times
I reviewed your code and video provided. It's great you was able to minimize the code used to reproduce that. Please attach a runnable test case, so we will be able to debug this problem. Unfortunately, I can't suggest you something meaningful without debugging.
First step - please try to comment the code causes the error in console. As you know, it might be critical for JavaScript thread.
All the best,
Alex