Complexity is the root of all evil. So how do we make simple webapps in Fulcro?
The key here is I think a good separation of concerns. In particular:
Separate rendering and business logic. Render functions (i.e. defsc
bodies) contain no or minimal logic, ideally at most simple conditionals or applications of external, pure functions that produce in-line derived data (that is not worth pre-computing externally). This is partially enabled by the fact that props are optimized for the UI, i.e. they contain exactly the data the components need. Pathom is the "backend for frontend" responsible for returning the data in the optimal tree shape but also with the optimal content, adapting from the general domain data (as stored in a database) to the specific UI needs. Changes to the state and side-effects are triggered from the UI but defined and processed externally. They are defined by Fulcro mutations, "transacted" as data, and processed separately, with hooks for customization of the process. Finally, any complicated logic that requires collaboration between multiple actors (multiple components and/or the backend) can be offloaded to Fulcro’s (pretty simple) UI State Machines (or statecharts).
The (whole) UI is a simple function of data. The application state (the "client DB") is turned into a tree of props and passed to the Root component. It then flows unidirectionally down to child components and all the way to the leaves. When there is a defect, in 95% of the cases, you only need to look at the data in the client DB.
Separate domain-specific and general UI code. I am not very clear on this yet. But when we look at e.g. a RAD report, we see that the only domain-specific part is where does the data come from (source-attribute
) and what columns (columns
) to display. (Plus minor props such as the title.) The whole rendering and behavior of the report has nothing to do with the domain and is defined by a bunch of generic "design" components and a state machine. Similarly, a domain-specific Fulcro component such as Teacher
would likely delegate its rendering to a couple of generic, domain-agnostic view components (and possibly some other domain-specific components for child entities). I have the feeling that JS React applications break the UI into too many, too tiny components stacked deeply together and then have to deal with passing data through all these layers.