Open SevereOverfl0w opened 1 year ago
Thanks for the report.
I haven't tested this, but since it's the defnc
macro that does the fast-refresh detection, I think this is only a problem for things that gensym new bindings in the reader. E.g. if you have a macro that gensyms some binding,
(defnc my-component
[]
(hooks/use-effect [] (my-thing-that-generates-some-bindings-internally))
,,,)
The code used by defnc
will be the non-macro-expanded forms. It's only because the anonymous function syntax expansion happens in the reader that this is a problem. I think.
Based on my reading here https://github.com/clojure/tools.reader/blob/fb185af411fa379e48e5d0a9e623b68f552d8c92/src/main/clojure/clojure/tools/reader.clj#L528-L532 I think that detecting the #
at the end of the binding seems easiest.
PR welcome!
FYI I had a similar issue in UIx, here's the fix, perhaps it can help https://github.com/pitch-io/uix/commit/7c39a4e38b7d665f99d727127cdb6e8d376d66e7
Simple reproduction that will cause fast refresh to always do a full reload:
It will be fixed by using
(fn [%] (identity %))
instead. The problem is that on each reload the gensym'd binding that replaces%
is changed. Compare:I don't have an clear idea on how to best fix this. If there was a way to detect & remove gensym'd symbols, that would be ideal. I don't know think that's possible at all.
The anonymous function syntax seems likely to be the most common (only? is this something that can only happen from syntax, or could a macro cause it too?) cause of this and it will always end its binding with
#
, or you could pick up on the prefix ofp\d+__
for that case, too.