A minimalistic ClojureScript interface to React.js
Adriaan Callaerts 2020-11-03T08:34:20.180Z

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?

Adriaan Callaerts 2020-11-04T10:10:09.186800Z

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!

p-himik 2020-11-03T08:42:53.180100Z

You need reader conditionals so that that code exists for CLJS but doesn't exist for CLJ.

Adriaan Callaerts 2020-11-03T08:44:00.180300Z

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]])
     (:refer-clojure :exclude [atom])
     (:require [reagent.core :refer [atom]]))
  #_#?(:clj (:require [cljs-css-modules.macro :as css])))

Adriaan Callaerts 2020-11-03T08:44:53.180500Z

(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)

Adriaan Callaerts 2020-11-03T08:45:20.180700Z

The current attempt results in error Feature cannot be (:require [...]) Features must be keywords.

Adriaan Callaerts 2020-11-03T08:46:03.180900Z

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?

Adriaan Callaerts 2020-11-03T08:48:15.181100Z

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]])))

Adriaan Callaerts 2020-11-03T08:55:51.181300Z

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.

p-himik 2020-11-03T09:00:37.181500Z

Are there any details about the spec error?

p-himik 2020-11-03T09:01:34.181700Z

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.

Adriaan Callaerts 2020-11-03T09:01:35.181900Z

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]])))

Adriaan Callaerts 2020-11-03T09:03:19.182100Z

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

Adriaan Callaerts 2020-11-03T09:03:54.182300Z

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

p-himik 2020-11-03T09:07:51.182600Z

The code that uses ratom must also be under a reader conditional.

Adriaan Callaerts 2020-11-03T09:11:07.182800Z

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

p-himik 2020-11-03T09:13:10.183Z

Ah, I see.

lilactown 2020-11-03T16:11:05.183900Z

You can’t have multiple :require statements in your ns expression

lilactown 2020-11-03T16:11:29.184800Z

You need to put the reader conditionals inside the require

Andrei Stan 2020-11-03T18:59:45.185900Z

hi. does reagent has a "native" alternative to dropzonejs ?

Andrei Stan 2020-11-05T19:45:47.187600Z

thank you @juhoteperi

juhoteperi 2020-11-03T19:16:22.186Z

Using React component is pretty much as native as it gets: