In above screen as indicated - I put some value in student name textbox. The value entered in this textbox is saved in the component state. I click "Show name of student". Inside event handler I just display the value of state and it shows the right value.
Now I do following steps
Select start end which is less than end date
Click Get button
Scheduler shows project and module
Click Add Event inside the scheduler
Enter event details
Click Save
Inside click handler I am trying to access the name of student from state but I don't get any value
StateValue2.PNG (52.35 KiB) Viewed 1559 times
Why is that event handler of scheduler control does not get any state values of the component in which it is present ?
Actually, this is more React question than Scheduler question because the problem you are facing is cause by how the hook useState and React functional components work.
What is happening is that when the Scheduler is created the listener functions are create together with their context at the time of creation. That means that each listener function will have an access to nameOfStudent but only to its initial value what is empty string in your case.
The solution is useContext instead of useState because context will be saved on the upper level (for example in App.tsx) and will be made available by lower level components.
While solution suggested by you works. I am still unclear as to why a normal button click event handler would get state value and why scheduler event handler not get state value.
Are you saying that we should use Scheduler with Class based component instead of functional components ?
what is actually happening is that with Scheduler we work the other way how React is designed to work. React watches changes in props and state and re-renders its content (html markup) , including re-generating functions, as needed of its own volition. However, we do not want Scheduler (its markup) to be destroyed from outside so we prevent it from being re-rendered by React. Then it runs in "old context" so to say and it can only access the original state.
The above works from the React viewpoint and it behaves as you would expect. However, it creates new Scheduler whenever the text state variable changes. The existing scheduler is not properly destroyed because we would need to call its destroy() method. That we could do before creating the new one but then we would lose state (scroll position, zoom state, perhaps some data too).
The solution is apparently easy, let's make the test if the scheduler already exists and create the new one only when it doesn't:
// ...
schedulerRef.current = schedulerRef.current || new Scheduler({
// ...
Now, scheduler is preserved but our listener always logs Initial Text.
I hope this answers your first question.
To the second: No we do not suggest class-based design of your app. We use class-based wrappers only because of backwards compatibility with React versions that did not support hooks. Use hooks freely, only remember that if you need to access data from the local state in Scheduler listeners or renderers you need useContext (or Redux, or another approach).