Fork me on GitHub
Vít Kalisz19:12:22

Hi, I am trying to introduce Material-UI to my project. In order to do that, I am doing some experiments on an example project I found here: After small adjustments, it worked fine until I updated the libraries in package.json and shadow-cljs.edn to current versions. Now, I get following error:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Could you please help me out and maybe provide an up to date version of this example?


The example uses a quite outdated version of Material-UI. You should probably just delete everything within layout.cljs and build something based off of one of the Material-UI examples for JS.


It definitely uses a deprecated MuiThemeProvider that will be removed in v5. It seems that the path of this class has changed, so likely the top require in layout.cljs must be rewritten.

Vít Kalisz19:12:28

Yes, I figured this out, but it still doesn't work after correction.

Vít Kalisz19:12:35

I didn't find another example with shadow-cljs so If you have one, please send me the link.


Either the correction was wrong or there is something else that's broken. Try to disable every usage of Material-UI and start from there, adding the components back one by one. Shadow-cljs doesn't really mean anything here. The only reason it's important is that it can properly require stuff from NPM modules. The way to require stuff is documented here:


You should be able to rewrite any CLJS Material-UI example so that it uses such require forms from the table.

Vít Kalisz19:12:34

Will do! Thank you for your help. 🙂

👍 4
Vít Kalisz19:12:01

Yeah still something broken with the ThemeProvider

useTheme.js:16 Uncaught TypeError: _react.default.useContext is not a function


useContext is a React hook. Right now, Reagent doesn't support hooks.


There should be an alternative way to use themes in Material UI though. You don't really need hooks.

Vít Kalisz20:12:40

Could you please have a look at this and tell me, whether this is an up to date piece of code I can follow?


The Material UI dependency version seems to be more or less recent, so I'd say yeah. I wouldn't use cljsjs though - I definitely prefer working with NPM and shadow-cljs.

Vít Kalisz20:12:45

They include this

["@material-ui/core" :as mui]
on the 4th line of the example. How do I do this in shadow-cljs?


Don't do it. It will include the whole Material-UI, even if you use just a single button. Just use something like ["@material-ui/core/Button" :default Button].

Vít Kalisz20:12:25

So how do I include the ThemeProvider than?


["@material-ui/core/styles/ThemeProvider" :default ThemeProvider]?

Vít Kalisz20:12:36

No that doesn't work.

Vít Kalisz20:12:02

The required JS dependency "@material-ui/core/styles/ThemeProvider" is not available, it was required by "app/layout.cljs".


Ah, try without core.


For future reference - just look at where the required module is within the node_modules directory.

Vít Kalisz20:12:57

So I have this:

(ns app.layout
  (:require [app.lib :as lib]
            ["@material-ui/core/styles" :refer [createMuiTheme withStyles]]
            ["@material-ui/styles/ThemeProvider" :default ThemeProvider]
            ["@material-ui/core/colors" :as mui-colors]
            ["@material-ui/core/CssBaseline" :default CssBaseline]
            ["@material-ui/core/Typography" :default Typography]
            [goog.object :as gobj]))

(def custom-theme
    #js {:palette #js {:primary #js {:main (gobj/get (.-red ^js/Mui.Colors mui-colors) 100)}}}))

(defn custom-styles [^js/Mui.Theme theme]
      #js {:button #js {:margin (.spacing theme 1)}
           :textField #js {:width 200
                           :marginLeft (.spacing theme 1)
                           :marginRight (.spacing theme 1)}})

(def with-custom-styles (withStyles custom-styles))

(defn frame []
       [:> CssBaseline]
       [:> ThemeProvider
        {:theme (custom-theme)}
        [:h1 "This is my first, simple heading ..."]]])
And I really don't know, how to get it to work. Please help me out.


So, what is not working?


Do you see any error messages or some undesired behavior?


It rather clearly tells you at the top of the very first exception stack trace that custom-theme is not a function. Why did you wrap custom-theme in parentheses? The original example doesn't wrap it.

Vít Kalisz20:12:01

Ou yeah. That was a mistake. I wanted to discuss this.


What version of React do you have?

Vít Kalisz21:12:31

16.12.0 This is the whole package.json:

"name": "MUI_EXP",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "watch": "shadow-cljs watch app",
    "compile": "shadow-cljs compile app",
    "release": "shadow-cljs release app && cp assets/* out/dist/",
    "html": "mkdir -p out/dev && cp assets/* out/dev/",
    "serve": "yarn html && http-server out/dev/",
    "clean": "rm -r out/dist/*",
    "dev": "yarn html && yarn watch",
    "repl": "shadow-cljs cljs-repl app",
    "build": "yarn clean && yarn release"
  "dependencies": {
    "@material-ui/core": "4.8.0",
    "@material-ui/icons": "4.5.1",
    "create-react-class": "^15.6.3",
    "react": "16.12.0",
    "react-dom": "16.12.0"
  "devDependencies": {
    "http-server": "0.11.1",
    "shadow-cljs": "2.7.10"
  "author": "",
  "license": "UNLICENSED",
  "private": true


OK, this does seem strange. Do you have a repo somewhere that I could clone and check out?

Vít Kalisz21:12:14

I'll put it on github and send you a link.


It worked for me just fine. Well, I had to manually copy index.html to out/dev so the dev HTTP server of shadow-cljs could find it, but it worked. Try updating shadow-cljs to the latest version.

Vít Kalisz21:12:27

I'll do that.

Vít Kalisz21:12:08

OK I updated the version of shadow-cljs and everythink works just fine.

Vít Kalisz21:12:17

Thank you very very much for your help and patience!

👍 4