Fork me on GitHub

what's the right way to reactify a component that uses hooks?


I believe it's r/as-element This document should have some more info that might be helpful


I haven't tested such case probably. reactify-component takes the "Reagent compiler" as the second param so (reactify-component component-fn (create-compiler {:function-components true}) should work. The option will also affect any [ ] inside that component.


You could create React function component with just defn and then returning React elements from that using create-element BUT in that case Reagent doesn't wrap the component in Ratom support things, so Ratoms wouldn't work correctly in that case.


Without using the reactify-component compiler option, you might need extra component so you can add :f>:

(defn fn-component [...] ...)
(defn fn-wrapper-component [...] [:f> fn-component ...])
(reactify-component fn-wrapper-compoent)
Here the wrapper component can be "reactified" like normal, as a class component, and it will use :f> to mark the children to use function component impl.


cool, thanks!

Roman Liutikov19:10:22

Does re-frame/reagent have a dev time warning on dereferencing app-db directly in a component instead of using subscriptions? I think this type of warning/error makes sense since it’s an anti-pattern leading to poor performance.


Re-frame's public API is only in re-frame.core. Everything else is an implementation detail, including app-db.


And even if you somehow managed to implement such a warning (which does not exist), anyone would be able to easily circumvent it by using

(reg-sub :db
  (fn [db _] db))

Roman Liutikov19:10:24

So it doesn’t exist :thumbsup:


And it wouldn't make sense to implement it. :)


I think the point of a warning is to help encourage good design and discourage bad design, which certainly does make sense as something worth implementing imo.


Once again - everything that's not a part of re-frame.core is not a public API. Even if that's not stated anywhere (although I'm pretty sure it is), there's a very explicit comment near re-frame.db/app-db telling you to not use it. Apart from that, there are infinite bad patterns one can do. You simply can't guard against them all. And in this particular case, guarding against direct derefs of app-db in views is absolutely not feasible.


Unfortunately the implementation might not be very simple. Re-frame would need to reify Ratom or something for the app-db and check some dynamic context inside deref method, and the proper deref places would need to set up this context. Perhaps not too complex, but ensuring it doesn't affect performance (perhaps by only enabling in dev builds) adds some complexity. And there are some (usually dev time) cases where you might anyway want to deref app-db directly, if you know what you are doing.