Hi all! This is probably a straight-forward question, but I've done some googling and can't seem to hit the right keywords to get the answer I need: how would I require and then use a reagent atom in a cljc namespace?
I tried that, but then I started to get other weird errors from the oops.core dependency, so I decided to dedupe the component into a clj and cljs variant after all. Thanks for the help anyway!
You need reader conditionals so that that code exists for CLJS but doesn't exist for CLJ. https://clojure.org/guides/reader_conditionals
I figured something like that, but then I can't seem to find out how to combine this with some other requires.
(ns fleet-frontend.fe.components.filter (:require-macros [cljs-css-modules.macro :as css]) (:require [oops.core :refer [oget]] [fleet-frontend.fe.components.icon :refer [search]]) #?(:cljs (:refer-clojure :exclude [atom]) (:require [reagent.core :refer [atom]])) #_#?(:clj (:require [cljs-css-modules.macro :as css])))
(I've tried a few variations where I'm using :include-macros in the cljs-specific bit etc to get the cljs-css-modules.macro ns to load, and then the icon ns and oops.core always need to be loaded)
The current attempt results in error
Feature cannot be (:require [...]) Features must be keywords.
Which I'm guessing is due to me having two
:require's in the ns form, because each seperately doesn't seem to be invalid I think?
For reference, this seems to be doing better (although I haven't confirmed it functions, at least it's compiling now):
(ns fleet-frontend.fe.components.filter #?(:cljs (:refer-clojure :exclude [atom])) (:require-macros [cljs-css-modules.macro :as css]) (:require [oops.core :refer [oget]] [fleet-frontend.fe.components.icon :refer [search]] #?(:cljs [reagent.core :refer [atom]])))
Another update: this seems to work for initial compilation, but then when the auto-reload kicks in it throws an error
Call to clojure.core/ns did not conform to spec.
Are there any details about the spec error?
Also, just in case - you can avoid having to put
:refer-clojure ... :exclude there by creating an alias for ratom or
reagent.core namespace as opposed to referring to ratom by name.
This is all I get:
Compile Exception src/fleet_frontend/fe/components/filter.cljc line:1 column:1 Call to clojure.core/ns did not conform to spec. 1 (ns fleet-frontend.fe.components.filter ^--- 2 #?(:cljs (:refer-clojure :exclude [atom])) 3 (:require-macros [cljs-css-modules.macro :refer [defstyle]]) 4 (:require [oops.core :refer [oget]] 5 [fleet-frontend.fe.components.icon :as icon] 6 #?(:cljs [reagent.core :refer [atom]])))
I figured I would have to do the refer [atom] and exclude [atom] to a) in case of clj use the built-in clojure.core/atom and b) in case of cljs use the reagent atom to get a component that at least seems to work in both
If I just use the reagent ratom in cljc it'll complain in the clojure-side of things because ratom is cljs-only as far as I can tell
The code that uses ratom must also be under a reader conditional.
but then wouldn't I also have to make every part of the code that derefs the ratom conditional? This was kinda what I am trying to avoid. I'd love to have a cljc component that uses a derefable for internal state. In client-side that would obviously be the ratom, but I don't want to rewrite the entire component for server-side to avoid having the ratom there
Ah, I see.
You can’t have multiple :require statements in your ns expression
You need to put the reader conditionals inside the require
hi. does reagent has a "native" alternative to dropzonejs ?
Using React component is pretty much as native as it gets: https://react-dropzone.js.org/
Or simple implementation in Cljs is like 40 lines: http://metosin.github.io/komponentit/#!/example.filepicker https://github.com/metosin/komponentit/blob/master/src/cljs/komponentit/filepicker.cljs#L67-L105 https://github.com/metosin/komponentit/blob/master/example-src/cljs/example/filepicker.cljs#L31-L50