This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-06-24
Channels
- # babashka (11)
- # beginners (62)
- # calva (9)
- # cider (7)
- # clj-kondo (18)
- # cljfx (2)
- # cljsrn (4)
- # clojure (55)
- # clojure-australia (3)
- # clojure-dev (2)
- # clojure-europe (39)
- # clojure-italy (3)
- # clojure-nl (3)
- # clojure-spec (5)
- # clojure-uk (5)
- # clojured (7)
- # clojurescript (16)
- # clojureverse-ops (2)
- # conjure (22)
- # cursive (12)
- # data-science (13)
- # datomic (8)
- # duct (7)
- # emacs (11)
- # events (1)
- # fulcro (12)
- # helix (10)
- # integrant (21)
- # introduce-yourself (5)
- # jobs (2)
- # jobs-discuss (16)
- # lsp (1)
- # malli (5)
- # meander (7)
- # membrane (9)
- # pathom (9)
- # reitit (5)
- # releases (3)
- # ring (2)
- # sci (18)
- # shadow-cljs (35)
- # sql (15)
I have a JSX component that returns a React component:
import React from "react";
import Select from "react-select";
import Survey from "survey-react";
const CustomSearchWidget = ({ choices, onChange }) => {
...
return (
<Select
...
/>
);
};
export const SearchWidget = {
...
render: (question) => {
return (
<CustomSearchWidget
...
/>
);
},
};
When I compile this using babel with npx babel *.jsx --out-dir gen
and import this compiled file in a clojurescript file like so:
["./surveyjs/widgets/gen/SearchWidget.js" :refer [SearchWidget]]
and use the SearchWidget in the application I get this error:
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object
If I return <div/>
instead of <Select/>
this error does not occurFull code:
import React from "react";
import Select from "react-select";
import Survey from "survey-react";
const CustomSearchWidget = ({ choices, onChange }) => {
const handleChange = (option) => {
onChange(option.value);
};
const options = choices.map((choice) => {
return { label: choice, value: choice };
});
return (
<Select
className="basic-single"
classNamePrefix="select"
isClearable={true}
isSearchable={true}
name="color"
options={options}
onChange={handleChange}
/>
);
};
export const SearchWidget = {
name: "search dropdown",
title: "Dropdown with search",
isFit: function (question) {
return question.getType() === "searchdropdown";
},
activatedByChanged: function (activatedBy) {
Survey.JsonObject.metaData.addClass("searchdropdown", [], null, "text");
Survey.JsonObject.metaData.addProperties("searchdropdown", [
{ name: "choices", default: ["Click Me"] },
]);
},
render: (question) => {
return (
<CustomSearchWidget
choices={question.choices}
placeholder={question.title}
onChange={(val) => (question.value = val)}
/>
);
},
};
(And it goes wrong when importing like so):
(ns nl.mediquest.questionnaire-frontend.component.survey
(:require
["./surveyjs/widgets/gen/SearchWidget.js" :refer [SearchWidget]]
[survey-react :refer [Survey StylesManager CustomWidgetCollection]]))
(.. CustomWidgetCollection -Instance (addCustomWidget SearchWidget "customtype"))
package.json
{
"devDependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.14.6",
"@babel/plugin-transform-react-jsx": "^7.14.5",
"shadow-cljs": "2.10.12"
},
"dependencies": {
"@fortawesome/fontawesome-pro": "^5.13.0",
"@fullhuman/postcss-purgecss": "^2.0.5",
"autoprefixer": "9.8.0",
"global": "^4.4.0",
"postcss-cli": "7.1.1",
"postcss-import": "^12.0.1",
"react": "^16.13.0",
"react-dom": "16.13.0",
"react-select": "^4.3.1",
"recharts": "1.8.5",
"survey-react": "^1.8.4",
"tailwindcss": "1.4.6"
},
"scripts": {
"build-css": "node_modules/postcss-cli/bin/postcss resources/public/css/tailwind.css -o resources/public/style.css"
}
it is something with the Select
component, because when I turn it into <div/>
the webpage renders and there are no errors
Is there a workaround for this?
@erwinrooijakkers you ...
out a bunch of code so I cannot see what this SearchWidget
actually is. from what you left in it is not a correct react component and that is what the error is telling you?
maybe you just forgot a export const SearchWidget = class extends React.Component {
?
Thank you. I added the full code in the reply
export const SearchWidget = class extends React.Component {
gives babel compilation error:
Unexpected token (28:6)
26 |
27 | export const SearchWidget = class extends React.Component {
> 28 | name: "search dropdown",
| ^
with npx babel *.jsx --out-dir gen
these are functional components I understand from the party that helped made them, so cannot add a class extends React.Component, although they say in the end itโs the same
so whatever it is it is invalid. it has nothing to do with shadow-cljs, it is purely a react error
I fixed it by changing:
import Select from "react-select";
to
const Select = require('react-select');
the same code did work in javascript for some reason
in the create-react-app
anyway
thanks for the help!
I'm using shadow-cljs, with the helix library.
I'm noticing that a tagged js literal such as #js []
when placed anywhere within the form of a call to react/useState, breaks the hooks state preservation on hot reload.
For example test-state
is preserved if I make a code change with this component:
(defnc test-component []
(let [[test-state set-test-state] (react/useState (do [] 1))]
($ "button" {:on-click #(set-test-state inc)} (str "test1: " test-state))))
but if I tag the array inside the do form with a #JS like the following, the state of test-state is not preserved if I make a code change:
(defnc test-component []
(let [[test-state set-test-state] (react/useState (do #js [] 1))]
($ "button" {:on-click #(set-test-state inc)} (str "test1: " test-state))))
maybe this is not a shadow-cljs issue, but any help would be much appreciated, thanks!simply to demonstrate that it's some sort of reader issue. The empty array never even reaches react/useState only the '1' does.
maybe helix does some stuff in a macro. I don't really know how hot-reload works with hooks. I would assume useState
is always lost, just like local state is normally lost. given that component type changes it should go through a full unmount/mount cycle
the weird thing is it seems to be related to the tagged literal. If I write
(defnc test-component []
(let [a #js []
[test-state set-test-state] (react/useState (do a 1))]
($ "button" {:on-click #(set-test-state inc)} (str "test1: " test-state))))
it works fineAnd this works fine also
(defnc test-component []
(let [[test-state set-test-state] (react/useState (do (array) 1))]
($ "button" {:on-click #(set-test-state inc)} (str "test1: " test-state))))
that's what makes me think it's either clojurescript or shadowreally need to ask in the #helix channel. I don't have a clue what defnc
does internally
ok thanks very much ๐
ah brilliant, that's very helpful, I guess it's analysing the code for calls to react hooks and something about the tagged literal is tripping it up, cheers