Hi, is there an easy to follow example on how to integrate helix components with devcards so that I can use :history true
I feel this should be easy, but there are so many new things everywhere, I find it hard to orient myself in what is relevant and what is not, spending hours googling without results
I asked this on beginners, but I don't know if it isn't just something specific to helix: https://clojurians.slack.com/archives/C053AK3F9/p1586851549325700
So yeah, I don't see how I could pass state hooks from outside when they can't be created, just on the inside. So history with use-state is probably never going to work
hey @ashnur. helix is doing some magic that prevents you from passing in a dynamic map as the first argument
the reason is that a React element needs to be created in a way that differentiates between props and children. A React element is basically an object like:
#js {:type AssetSelectControl
:props #js {}
:children #js [,,,]}
when you create an element with $
, it has a couple rules:
• if the first argument is a literal map ($ AssetSelectControl {})
it will convert the map to a JS object and put it in the :props
key
• if the first argument is not a literal map ($ AssetSelectControl foo bar)
, it will add it to the :children
key
it does this logic at compile time, to avoid doing a bunch of runtime checks to see if the first argument is a map or not (and slowing down your code, if you’re creating a lot of elements over and over again)if you want to pass in a dynamically created map (like your @state
value) you can use a special keyword or symbol, &
to merge them in
all of this and the &
keyword/symbol are explained in the docs: https://github.com/Lokeh/helix/blob/master/docs/creating-elements.md#dynamic-props
@lilactown Hi, I figured the {:& @state} trick to solve my props problem
right now I am trying to somehow use devcards and helix together, but I am not sure how. I think with use-state it's not even possible
But maybe with use-reducer?
and a context hook
helix and devcards are 💯 compatible
helix uses devcards for test cases and examples
https://github.com/Lokeh/helix/blob/master/dev/workshop/core.cljs
the trick is that you cannot use hooks inside the devcard
you need to use hooks inside of a component, and then pass an element to the devcard
@lilactown I am not sure we talk about the same thing. I would like to be able to use :inspect-data true
and :history true
with functional components that get the return value of a useState()
call passed to them through props.
This would allow me to feed whatever data to the component while not maintaining the state myself
can you give me some example code?
“the return value of useState
” is just a tuple [state set-state]
. there’s nothing special about it
your component should be designed in a way that it doesn’t depend on the exact shape. instead, you should have a prop that takes a value and a prop that takes a callback that updates the state
e.g. take the input
component:
(helix.dom/input
{:value state
:on-change #(set-state (.. % -target -value))})
This of course works, I found it. I've been playing with helix for days now, I got almost everything working. I can't define a defcard to use a component and pass the state to it because React doesn't allow hook calls outside of it
something similar to the state-reset example here http://rigsomelight.com/devcards/#!/devdemos.custom_cards
you can totally do this. you must not pass in the state atom directly
(defcard state-over-time-view
(fn [state _]
($ your-component
{:value @state
:on-change #(swap! state ,,,)}))
{:x 0})
devcards listens to changes to state
and will call the (fn [state _] ,,,)
again anytime it changes
it doesn’t call use-state
but that’s OK, because a parent component calling use-state
and passing the value/setter into your-component
would behave the exact same as it does here
totally works as you said. It shows how clueless I am : (. Thanks @lilactown, I owe you big time.
been trying to do this for almost two days now, although in the beginning I didn't even know how to pass props, I tried ($ ComponentName @state)
and was wondering why it didn't work
then some kind people in the beginners explaind the whole thing with macros, and literals and reader form and then I foun dynamics props, but I was still trying to somehow wrap devcards in react...
helix isn’t the most beginner friendly yet. the best advice I can give is to read the documentation carefully, and let me know if there’s anything that is confusing. I’ll try and improve it as I get more feedback!
I’ve mostly written helix for myself and a group of people who are fairly familiar with ClojureScript already, so I’m sure there’s things that I have missed or not explained well
that is to say, I’m sure it’s not just you 😄
so, the situation is that, I am a beginner in clojure for the 8th year now
I used datascript in javascript in 2015
I know React because I regularly read the source code : )
It's just that until now I was unable to set up the dev env, and the only reason I was able to get something going right now was because of this package https://github.com/filipesilva/create-cljs-app
I really like the architecture of om-next, but it's a bit heavy. I wanted something that uses hooks well, and helix was one of the first things I found and when I read the thing about hiccup I knew I will like it. I was just very lost about how to use devcards.
now the question is, if I start adding specs to this codebase, can I run frontend tests inside devcards? Because I saw it here that maybe that's not the case. https://github.com/bhauman/devcards/issues/157#issuecomment-468375929 Or what is my best option to runt spec based tests? Just follow official docs?
hmm I’m not sure
currently, helix components are not spec-able
i.e. you cannot fdef
a component
I have a task in my backlog to explore how to properly spec a component
I know how to do it in javascript land with json schema, you need 3 different schemas, • app/local schema that describes state that is important for the component to write (not probably read also, but the write is the key, every state has only one writer/owner, right?) • UI schema that describes what needs to be displayed and how it can be displayed, this can be just an image or a full form validation, but it's not about application state, it's just about what the U in the UI does, so the writer is the "user" in a way, derived data might be part of the previous category • remote state, for each different endpoint you want to write state you can describe the shape it expects That's all. I actually prefer react components to not control any state just dispatch actions, but the above works with local state too. And I claim that's a complete analysis, there is no fourth category and these categories do not overlap.
But right now I would be fine to just have some pure functions specced and tested, the components if they are not fully tested is ok.