You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We currently store non-serializable class instances inside the Redux store (e.g. here and here). That is because we encode specific behaviour of each element type / relationship type of each diagram type using a dedicated class (like this) and have generally organised such functionality over a hierarchy-tree encoded with inheritance.
Do Not Put Non-Serializable Values in State or Actions.
Avoid putting non-serializable values such as Promises, Symbols, Maps/Sets, functions, or class instances into the Redux store state or dispatched actions.
As explained in this answer, unfortunately this rule also means use of inheritance, as currently implemented in Apollon, is also not possible while following Redux's essential guidelines.
Current implementation, in some situations, specifically leads to redundant re-rendering, as the whole instance is replaced with a new one and redux is unable to trace down the changes. It is also a potential source for other issues (such as debug tools not working properly) and footguns (methods that mutate objects having apparently no effect).
Describe the solution you'd like
We should keep plain objects in Redux.
This can be achieved by moving functionality of current class methods to some standalone helper functions, taking the instance as their first argument, and producing the necessary result. For each type-agnostic functionality (i.e. method of a parent class), we can have helper functions routing based on element (or relationship) type to the type-specific implementation, or fallback to a more generic implementation working for a wider range of element (or relationship) types.
This solution effectively results in some pseudo-implementation of OOP in a customised manner. Tracing deeper inheritance chains would be difficult and complex, but simpler chains would be easily resolved.
As it currently stands, most element and relationship classes do not add any specific functionality except for their custom component, which is already registered with a similar mechanism and not via class inheritance. This change might reduce the size of the code base drastically.
Since Apollon code base is in TypeScript, this solution would also require equivalent types and interfaces for various element and relationship types (where currently we have classes).
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem?
We currently store non-serializable class instances inside the Redux store (e.g. here and here). That is because we encode specific behaviour of each element type / relationship type of each diagram type using a dedicated class (like this) and have generally organised such functionality over a hierarchy-tree encoded with inheritance.
❌❌ WE SHOULD NOT BE DOING THIS. Redux explicitly lists this requirement as an essential one:
As explained in this answer, unfortunately this rule also means use of inheritance, as currently implemented in Apollon, is also not possible while following Redux's essential guidelines.
Current implementation, in some situations, specifically leads to redundant re-rendering, as the whole instance is replaced with a new one and redux is unable to trace down the changes. It is also a potential source for other issues (such as debug tools not working properly) and footguns (methods that mutate objects having apparently no effect).
Describe the solution you'd like
We should keep plain objects in Redux.
This can be achieved by moving functionality of current class methods to some standalone helper functions, taking the instance as their first argument, and producing the necessary result. For each type-agnostic functionality (i.e. method of a parent class), we can have helper functions routing based on element (or relationship) type to the type-specific implementation, or fallback to a more generic implementation working for a wider range of element (or relationship) types.
For example, the custom
render()
method ofBPMNSwimlane
can be a function registered for this particular element type, and another helper function will try to retrieve the type-specific render function for each element type, falling back to a more generic one (or in this case, simply noop sincerender()
doesn't do anything except when it is overriden).The text was updated successfully, but these errors were encountered: