Fork me on GitHub
#reagent
<
2021-11-18
>
mauricio.szabo03:11:21

Just a question - does reagent makes some kind of optimization by itself? I was trying to use pure react to make some elements, but found almost no difference in performance

Santtu Lintervo08:11:44

Hello. newbie here testing reagent, and I have trouble getting build working. I created new project with lein new reagent reagent-test, run yarn, and then lein figwheel. Opened localhost:3449, and it shows “please wait while Figwheel/shadow-cljs is waking up ...“. In the console there are errors like: Uncaught TypeError: Cannot read properties of undefined (reading ‘render’) at reagent$dom$render_comp (dom.cljs?rel=1637224001428:18) Any clues what I’m missing here?

p-himik09:11:04

One of the reasons why templates can be worse than just creating a project from scratch by hand. When I ran the same commands, I got Error: Cannot find module '@cljs-oss/module-deps' during the first build. After running yarn add @cljs-oss/module-deps, I started getting Uncaught ReferenceError: $jscomp is not defined in JS console. IIRC this error usually indicates either a but in the build tool or some incompatibility between the built tool and some NPM module. You can try updating all the dependencies, especially Figwheel-related. If that doesn't work, might be worth asking in #figwheel As an alternative, you can try using shadow-cljs - a completely different build tool.

p-himik09:11:10

Regarding the error on the missing library - seems like it's been fixed: https://github.com/bhauman/figwheel-main/issues/21 So maybe just updating the dependencies will fix that one as well.

Santtu Lintervo10:11:32

ok, thx! just wanted to do “quick” testing but usually it does not work like that.. maybe invest bit more time and go the build-from-scratch route.

mauricio.szabo14:11:25

Also, can I recommend Shadow-CLJS? Figwheel got me into so many problems like this one that I tend to avoid it everywhere I can 🙂

Santtu Lintervo17:11:06

yes! read the documentation (which was surprisingly thorough, no tldr) and it seems very promising.

selfsame20:11:44

Hi friends, having a hard time using React components written in javascript that use hooks with reagent, does anybody know the conversion sigils for this?

p-himik20:11:37

It's pretty well documented in Reagent's repo.

selfsame20:11:32

@U2FRKM4TW think I'm missing something then, trying to do [:div [:> Foo]] where Foo is native and uses hooks but nothing i've tried or seen in the reagent docs seems to avoid the Invalid hook call errors

p-himik20:11:57

Can you post the full error?

selfsame20:11:01

note, we're not trying to write a reagent component that uses hooks, that is documented

p-himik20:11:22

React component that uses hooks is just a React component - there's nothing special about it.

selfsame20:11:43

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See for tips about how to debug and fix this problem.

p-himik20:11:54

Have you investigated items 1 and 3 in the error?

selfsame20:11:23

Yes it's not multiple versions of React

selfsame20:11:51

same error if you try and instantiate a simple hook using component outside of JSX

p-himik20:11:35

Does that Foo come from some publicly available library that's easy to use?

selfsame20:11:22

our simple test component is

const StripeTest = (props) => {
    const [count, setCount] = useState(0)
    return (
        <>
            <div>Nothing interesting: {count}</div>
            <button onClick={() => setCount(count + 1)}>+</button>
        </>
    )
}

p-himik20:11:06

Ah, so you're the one writing that component, alright. How exactly did you confirm that it's not multiple versions of React?

selfsame20:11:58

hmm possible there are two instances of the same React version, will investigate

Noah Bogart20:11:12

idiom question: i have a global app-state r/atom, and in a component i have r/with-let to make cursors onto various keys of app-state. should I be binding every part of app-state that I’ll need in that component or sub component at the top level or should I just bind some of them and deref for others?

p-himik20:11:17

Not exactly certain what the last part of your question means, but in general you should get your data as close to the place that needs that data. Otherwise, there will be unnecessary rendering. E.g. suppose you have a table where you get the data for all the cells at the table level and then feed that data to individual cells. In this case, if just one cell receives new data, the whole table will be re-rendered. But if you deref only in cells or create cursors and deref only in cells, then the whole table won't be re-rendered when just a single cell changes.

Noah Bogart20:11:23

let me see if i’m getting this right. creation of a cursor within a component doesn’t affect rendering. writing (:example @app-state) will rerender the component when app-state changes, but (let [example (r/cursor app-state [:example])] @example) will rerender only when :example inside of app-state has changed?

p-himik20:11:50

Yes and yes.

👍 1
Noah Bogart20:11:09

cool, thank you

p-himik20:11:15

Although don't create a cursor and deref it right then and there. The cursor should be in a with-let or in a form-2/form-3 component.

👍 1
Noah Bogart20:11:29

is there any reason to pass in a cursor to a component vs making the component form-2 and re-binding the cursor within?

p-himik20:11:18

What do you mean by "re-binding a cursor"?

Noah Bogart20:11:49

(defn component-2 []
  (r/with-let [example (r/cursor app-state [:example])]
    [:div
     [:p (str "Example 2: " @example)]]))

(defn component-1 []
  (r/with-let [example (r/cursor app-state [:example])]
    [:div
     [:p (str "Example 1: " @example)]
     [component-2]]))

Noah Bogart20:11:55

vs

(defn component-2 [example]
  [:div
   [:p (str "Example 2: " @example)]])

(defn component-1 []
  (r/with-let [example (r/cursor app-state [:example])]
    [:div
     [:p (str "Example 1: " @example)]
     [component-2 example]]))

Noah Bogart20:11:19

contrived example i know, but how a lot of my current codebase looks lol

p-himik20:11:35

Depends on what kind of components you're creating. The former example creates components that aren't reusable. And in the latter one, component-2 is reusable.

👍 1