Wow! Which version of reagent/MUI? Did you use webpack for bundle? You didn't get warnings about ReactDOM incompatibilties?
Ah I see. Thank you @vishal.gautam for the explanation on the hooks. I can see how they would be quite valuable in daily React land.
does this method
(ns app.navigation
(:require
[reagent.core :as r]
["@material-ui/core" :refer [List ListItem Button]]
["@material-ui/styles" :refer [makeStyles]]
["@material-ui/icons" :refer [ExpandMore ExpandLess BarChart] :rename {ExpandMore ExpandMoreIcon
ExpandLess ExpandLessIcon}]))
do automatic tree shaking on advanced compilation? If so it might be worth learning the technique. Is this shadow-cljs?You don't need hooks at all if you just use cljs with reagent/re-frame, but when you start doing interop and use js libraries, sometimes hooks are unavoidable. For example graphql lib apollo relies on hooks for the queries, and in react-native world you are missing a lot in react-navigation without effects, such as useIsFocused, useSafeArea, useHeaderHeight, useScrollToTop, and all the hooks related to animations
Also maybe I was doing something wrong but in previous versions of reagent I found it pretty hard to use hooks in components without losing some params in the clj->js->clj conversions (not losing completely but losing namespaces in keywords and sets in vectors)
FWIW, I'm using reagent 0.10 and material-ui 4.9.5 (via the cljsjs packages), works just fine. Not using any hooks, though.
FWIW I made some benchmarking between reagent, helix https://clojurians.slack.com/archives/CRRJBCX7S/p1588066976025300
1π(using latest stable version of reagent 0.10.0, not 1.0.0), config is here https://github.com/krausest/js-framework-benchmark/pull/726/files)
@schaueho gotcha. I'm including material-ui v4 in with npm via webpack/figwheel and I'm getting an error with reactDOM stuff. Let me see if I can replicate real quick...
Here's the issue. I get this error: https://reactjs.org/docs/error-decoder.html/?invariant=321 The minimal code that causes this is:
(def text-area (reagent/adapt-react-class js/window.MaterialUI.TextareaAutosize))
(def main-panel []
[text-area])
The build was:
yarn add material-ui
yarn webpack
with an index.js
(if you're familiar with this build style)
import * as MaterialUI from "@material-ui/core";
window.MaterialUI = MaterialUI;
and a dev.cljs.edn
that looks like
^{:watch-dirs ["src"]
:css-dirs ["resources/public/css"]
:npm {:bundles {"dist/index.bundle.js" "src/js/index.js"}}}
{:main project.core
:closure-defines {DEBUG true}
:output-to "resources/public/js/compiled/app.js" }
how do you fire an event as soon as the component has loaded, i.e., onComponentMount?
Check out Form-3 components https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
that's slightly verbose though. Is that the recommended way?
Yeah, as far as I know thatβs the only way to do it, short of rolling your own interop with React and JS.
it's not that bad @pshar10 there are just some pitfalls to be aware of. Use them all the time (for better/worse), ping if you run into trouble
if for some reason you use them inline just remember they need to be wrapped in a vector
what pitfalls do I need to be aware of?
I use them with inputs frequently to focus/select on mount, i.e.
(reagent/create-react-class
{:componentDidMount
(fn [this]
(let [node (reagent.dom/dom-node this]
(.select node)
(.focus node)))
:reagent-render
(fn [] [:input])})
if you were to drop that inline, for instance, you would need to do something like
[:form
[:label "blah"]
[(reagent/create-react-class
{:componentDidMount
(fn [this]
(let [node (reagent.dom/dom-node this]
(.select node)
(.focus node)))
:reagent-render
(fn [] [:input])})]]
(note that it is wrapped in a vector)
as opposed to
[:form
[:label "blah"]
;; this won't work
(reagent/create-react-class
{:componentDidMount
(fn [this]
(let [node (reagent.dom/dom-node this]
(.select node)
(.focus node)))
:reagent-render
(fn [] [:input])})]
the other two pitfalls, I suppose, are to access the actual dom node from the lifecycle methods use reagent.dom/dom-node
as indicated in the example and to make sure that your your render method is actually :reagent-render
. If you use :render
it will have intermittent bugs
@goomba This is better I think:
(def foo-bar
(with-meta identity
{:component-did-mount
#((foo-bar))}))
(defn my-component []
[foo-bar
[:div "Foo"]
]
)
Cool! I've never seen that before π
So based on the docs here: https://material-ui.com/getting-started/installation/
you need react >= 16.8 and the version in my /target/public/cljs-out/dev/cljsjs/react-dom/development/react-dom.inc.js
is var
ReactVersion = '16.13.0';
wait... I still don't see why that's an issue
anyway I fixed it with the following workaround
import * as MaterialUI from "@material-ui/core";
import * as React from "react";
import * as ReactDOM from "react-dom";
window.MaterialUI = MaterialUI;
window.React = React;
window.ReactDOM = ReactDOM;
and it works now Β―\(γ)/Β―
What figwheel version are you using? I get an error when passing from figwheel-main 0.2.0 to 0.2.1
@pshar10 With reagent 1.0.0 you can use functional components and react useState hooks.
squint that's a good question. I'm using cider-jack-in-cljs
so I'm not sure what it's using
I'm using the Material-UI packages from cljsjs and classical figwheel-main via leiningen. So not via yarn, so that might be why I've never run into a problem there.
Has anyone tried #respo and #reagent both? What are the pros and cons of both?
Which do you like better and why?