Hi all š, Iām getting started learning RN and using cljs + expo (+ reagent + re-frame) and working on my first project. An input field with the traditional Ratom as value is barely usable (wonky typing, same issue as web has sometimes). useState works fine. Iād rather not mix multiple approaches to manage local state, so this will push me over to use the hooks API and drop the ratom for local state in all components. I will be keeping re-frameās ratom for global state. Is this common practice / how does the rest manage text-inputs?
I use a re-frame subscriptions and handlers almost everywhere. Dispatching the handler on :on-change-text
. Seldom use local component state in other ratoms. Not seen this wonky behaviour you are mentioningā¦
Thanks for the input, Iāll try going through the re-frame store then (wasnāt set up yet) :)
It could also be an issue about wether it is controlled components or not.
This is the behavior in case you were wondering
Oh, wow.
Reagent in web has the same issue, but less often and less obvious. It has to do with component virtual re-rendering outside of the request animation frame
It ālooksā related but hey Iām just starting out with RN. What did you mean by controlled component?
The re-frame database is updated in request animation frames, I think. Controlled components: https://reactjs.org/docs/forms.html
Seems like the way to go then š
I usually kept ephemeral state local, like a toggle or simple inputs like search. Out of curiousity, how do you structure this in global state? Something like view namespaced keys at root? my-app.views.search/input-value "foo"
In the current project I am working with we use something we call āformsā. Itās basically a path into the database where we store maps with data like this. I kinda like the pattern. It makes it easy to examine the state of the UI from the REPL.
Cool, thanks for the insight
Why don't u share code? This has happened to me but i just want to confirm u are doing it
@lepistane do you mean from the input bug I showed?
yes
itās a basic form-2 with a reagent atom. Iāll make a snippet
yeah i am now even more sure what's the issue. make the snippet
Snippet is madeā¦ testing for bug confirmationā¦ loadingā¦
@yannvahalewyn I wrote a blog post about input fields and state: https://increasinglyfunctional.com/2019/03/28/why-clojurescript-react-native-text-input-slow.html
@joshmiller thanks, Iāll read that!
@lepistane hereās that snippet
(defn- broken-search-input []
(let [value (reagent.core/atom "")]
(fn []
[rn/text-input {:value @value
:placeholder "Edit me"
:on-change-text #(reset! value %)}])))
@joshmiller and i must thank you for this because u saved me few months ago with that blog post š i wanted to see the code before i gave advice @yannvahalewyn try the link āļø that's basically what i wanted to share š and it should fix your problem
I figured it out but thanks for the help guys! š
no worries, but all credit goes to @joshmiller always happy to see new people try the magic of cljs react native
Itās great! Was doubting but hearing that Iāll post a little first day hacking result for a beginner happy message
It can be super frustrating dealing with bugs, especially with the more brittle parts of the RN toolchain. But when it works thereās nothing else like it, itās so productive.
Some things were indeed frustrating. But since I know and love the productivity of the language from web dev I could power through thinking about whatās to come :)
Hi all š
So Iāve finished my first day of hacking on a cljsrn app. And thought Iād share a bit of joy and experiences casually with the community. It was great! I had fun! Then I was frustrated! Then I had fun again! You know how it goes š.
My relevant knowledge before today was experience with clojure, clojurescript, reagent, re-frame and lots of full stack day-job experience with it. I knew about React Native and the basic idea (because itās so mainstream, hard to miss) and I had setup a hello world with expo yesterday. Today I started studying and following tutorials but studying without a clear goal is extremely procrastinatable (yes, that most probably is a word) in my mind so I decided to just start building (f* it) and solve whatever I run into.
:thumbsup: The good
a.k.a: best day ever
First of all, Expo is a freakinā gift from the heavens for first timers š. I was putting this baby off because I knew setup was long and complicated (tried it once couple of years ago). I started by setting up emulators because I remembered setting up a dev device was harder. When I realized I could download an app, scan a barcode and have a development physical machine in my hand, my mind was officially blown š¤Æ. That was such a thrill and rush! I donāt own an iOS device for testing, and the lack of setup also opens a door to borrowing one and testing it out before release which is amazing for no-budget projects. If I was less stubborn and better at reading guides I wouldāve been writing and running code under an hour on a physical device without any prior knowledge of expo. Now it took me a couple š.
I managed to build way more than I thought would be possible in a first day with zero experience! Granted itās not much, itās just a static UI (screenshots below). But achieving this in a short timeframe using only docs shallowly proved that training a web developer to switch to a native project is a low effort high reward deal.
The biggest reason I got to be productive, next to Expo, was RNās adoption of base concepts in CSS. Having flex box, margins and padding is such a natural and productive way to style layouts and second nature for me that it didnāt require any time to get up and running. I appreciate Facebookās choice and design in the matter.
React Native components and expo modules have great documentation with clear examples, they were a breeze to browse and overall a great resource even for first time readers.
:thumbsdown: The bad
a.k.a: not horrible but just, way less good
Getting fonts up and running was mildly frustrating, I lost a bit of time trying to setup a (expo-google-) font and being able to use the :font-weight
attribute to bolden things. Using :font-family
on every element for every weight seemed a bit weird coming from web. Solvable by having a typography namespace with reusable components or any other abstraction of course, but the essence of the matter bothered me a bit. Iām probably missing something but couldnāt find any relevant real world examples. On the flip side, having expo expose (PUN INTENDED) all the google fonts in a simple module is a very friendly feature.
Scroll views were hard and unpredictable. Apart from messing with āflex 1ā parents, padding
on the scroll view also caused weird bugs. I ended up wrapping the children with a view with padding but I couldnāt (quickly) find what caused the issues.
Hot reload times are pretty bad on my machine. Hello world reloads in ~30s with a full refresh (seing the expo splash screen). Iām a bit worried about this when a project matures. Today it was a bit counter productive when styling components as my workflow is to space everything out too much and gradually reducing whitespace until it feels right. Iāve found https://github.com/flexsurfer/rn-shadow-steroid/blob/master/src/steroid/rn/core.clj#L11 that has itās own reload component (and bypassing fast-reload required) that Iām thinking about trying out. Usage demoād in this https://hackmd.io/@byc70E6fQy67hPMN0WM9_A/rJilnJxE8. Iām wondering how other people experience and handle this.
There are lotās of slightly different opinions and guidelines on when to use which of the Touchable* components, but a lack of real world examples and how you would develop cross platform UIās using them correctly. The official docs donāt seem to have an opinion on this. Iāll figure it out eventually but pointers are welcome.
There are not that many resources, real world example projects, relevant up to date blogs about CLJSRN out there. But thankfully, like for the web, itās not a bit step to translate JS examples to CLJS so Iām happy I can piggy back on the JS community for the most part.
There are not many best practices on how to structure a cross platform application out there. My current strategy is to just cross that bridge when I run into issues, but some general guidelines on what seems to work well would be a nice read. For example, I may want to share as much code as possible between iOS, android and web. Expo kinda builds for the web as well and seems to suggest this is a way to go, but instinctively Iām thinking I should write native views with some branches for ios/android and seperate web views (and share the other bulk of application code). The web feels like a different beast mostly in terms of features and accessibility that writing a solution that compiles gracefully to both is probably a source of headaches. Iām sure other people have run into this, solved this but no knowledge seems to be available or I havenāt found it yet.
š” The ugly
a.k.a: omg make it stawp
Big shock: errors and source maps! Almost every error I had would have a stacktrace to useFont.ts and a gibberish stack trace š
. Error message were either very useful (explicit RN messages) or complete gibberish. What I found amusing is that Iām used to this being the other way around. Seeing this issue: https://github.com/facebook/metro/issues/104 Iām not hoping on improvements soon. Today my workflow on errors was to uncomment code and enabling it piece by piece until Iāve found the culprit. This in combination with slow reload times was a big flow killer. Especially since I tend to save files less often because of the reload times, making the changes bigger and the debug process even bulkier. Any insights on how this is handled in bigger projects is more than welcome.
Conclusion
Overall, I am amazed by how far I got today and I had loads of fun. Coming from web and applying my knowledge efficiently on a native platform was an amazing experience and it feels like in one day Iāve managed to greatly expand my toolkit and reach as a developer without too much effort. Thanks for the hard worked of all involved, especially the React Native team and Expoās sublime efforts for making it accessible to NOOBS.
Here are some screenshots of my progress. Iām building a songbook app for performing singer (/songwriters). Structuring, managing, cooperating and labeling songs (lyrics and chords) will be the focus of this toy app.
Thanks for reading š
Awesome! Definitely keep hanging out, weāve all helped each other debug a whole bunch of issues here, and lots of times it helps to just have a pair of eyes that has seen an impenetrable stacktrace before.