I have a root query in my component:
[:root/current-course '_]
I expect it to return the tuple:
[:course/id 1]
But occasionally it denormalizes and returns
{:course/id 1 :course/name "my course"....}
This causes occasional white screens when for instance destructure the ID out of the tuple
I am running the latest fulcro cc3240fc with react 19
I did not run into this issue prior to switching to latest fulcro (the white screen) but will run tests to double check
Seems like it was caused by the combination of a root query
[:root/current-course '_] wihtout attributes which normally returns a tuple (the ident)
with an empty map as initial state
{:root/current-course {}}
as a result in the latest version of fulcro/react 19 it sometimes resulted in the prop :root/current-course briefly being the denormalized value of current course from app-db instead of the tuple
In the Root component you should not use link queries (you are already AT the root). As far as initializing them…that’s an interesting case, but the db is initialized before any render…where did you have the initializer? On Root? or on the component with the link query?
It wasn't the Root component,
{:use-hooks? true
:query [[:root/current-course '_]
[:root/current-timeframe '_]]
:initial-state {:root/current-course {}
:root/current-timeframe {}}}Oh yeah, you should never try to initialize a root key from a non-root component
I should probably add some kind of check/compile error for that
Another interesting React 19 upgrade bug:
(defn on-saved [uism-env]
(let [form-ident (uism/actor->ident uism-env :actor/form)
props (get-in (::uism/state-map uism-env) form-ident)]
(if (:ui/save-and-new props)
(-> uism-env
(uism/apply-action update-in form-ident dissoc :ui/save-and-new)
(uism/transact [(create-new-question {...})]))
uism-env)))
(uism/defstatemachine save-and-new-form-machine
(let [base-machine draggable-form/draggable-form-machine
handler-path [::uism/states :state/saving ::uism/events :event/saved ::uism/handler]]
(-> base-machine
(update-in handler-path
(fn [handler] (fn [env] (-> env handler on-saved)))))))
I updated the form-state-machine to support a "create and new" button, it simply calls on-saved after the :event/saved handler is called whe :ui/save-and-new is set. But with the fulcro/react-19 upgrade it doesn't work anymore, I get the warning that the I have unsaved changes and it routes back to the previous screenI'm not sure I understand what uism/transact docstring is saying,
Just like `components/transact!`, but simply queues the transaction to be submitted after the handler completes.
Usually you can use `apply-action` to do local state changes, and `trigger-remote-mutation` to do remote operations;
however, sometimes external users of a state machine wish to supply ad-hoc operations that should be run by a
state machine.
NOTE: It is legal to side-effect in an event handler, but in general the desired operation is to defer
the side effects (e.g. `comp/transact!`) until the handler has finished. Running, for example, a synchronous
transact inside of a handler will not work as expected because the handler will finish after such a transaction
and overwrite the changes to state that such a transaction caused.
does this mean that even though the transaction is queued to be submitted after the handler completes, it can still finish before the handler?
also the exemple seems incomplete:
So, for example, someone might begin a state machine with:
(begin! this machine :id actors {:on-success `[(something-happened)])
which the state machine can save with `store`, and later look up with `retrieve`.
`options` is as described in `components/transact!`.Ok the docstring is actually saying that comp/transact! might finish before the handler
> queues the transaction to be submitted after the handler completes. seems like it no longer is the case with react-19 for uism/transact
I have no idea how that would break. React has absolutely nothing to do with UISM internals. You sure you’re not relying on someething sending an event that is tied to the UI that couples it to rendering?
I am only extending the :event/saved handler https://clojurians.slack.com/archives/C68M60S4F/p1756736399121139?thread_ts=1756453412.062749&cid=C68M60S4F
@tony.kay main thing I'm doing in that mutation is calling rad-routing/route-to!
so in form-allow-route-change the pristine state is not updated yet when route-to! calls it
@tony.kay So I found one strong sign of an issue:
in the mutation if I check the content of :com.fulcrologic.fulcro.algorithms.form-state/forms-by-ident in '@state' even before calling rad-routing/route-to!, the pristine state which I get from @state has already been updated (which is expected).
but inside of form-allow-route-change the pristine state which is obtained from (comp/props this) is not up to date and still contains the old value
I'll try to dig more later but my hunch is that target-denying-route-changes in fulcro is passing outdated props to allow-route-change? somehow
it could be that the react rendering in 19 has a different timing. This is why I try very hard to separate the behavior of the app from the rendering. unfortunately, the dynamic routing system does have some reliance on react’s rendering. It was a poor implementation choice on my part (from very long ago). This is also why today I’m leaning very much towards applications that leverage statecharts even for the routing, so that things have a much better overall semantics.
A patch to the dynamic routing system that eliminates the use of indexes (of UI components) might help…but it’s a rather complicated refactoring
@tony.kay in the meantime wdyt of https://github.com/fulcrologic/fulcro-rad/pull/141
Odd. I didn’t change anything internal, and I thought that normalization picks things apart and then merges the final bits into app state. Not sure why you’d see the map ever, unless some other bit of your code did so without normalizing