Using React.forwardRef in Fulcro (and rendering a Fulcro component from a JS one)
How (and why) do you use React.forwardRef in Fulcro? Let’s first explore ref
. When you need access to the raw HTMLElement in React - f.ex. to call .focus
on it - you need to create a Ref object[1] (similar to Clojure’s atoms) and pass it to a React DOM element such as dom/div
via the magical property :ref
. React will then do something like "(reset! <the Ref> <the raw element>)" so that you can access the raw element in your code: (some→ <the Ref> .-current .focus)
. The :ref
property is magical in the regard that it is "consumed" by React itself and not passed to the component. But what if you make a custom component and want it to be able to take a Ref object to attach it to its child DOM element? The simplest solution is to pass it under any other name than the reserved ref
, which is exactly what this Fulcro examples does, using the custom :forwarded-ref
. However, some 3rd party higher-order components insist on passing the Ref down using the reserved ref
property name. To make it possibly, React invented forwardRef
:
const FancyButton = React.forwardRef((props, ref) =>
(<button ref={ref} className="FancyButton">{props.children}</button>));
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
Continue reading →
The trouble with list components in Fulcro
Imagine you have a list of things to display in your UI. You naturally want to represent them with a list component, such as a TodoList
. But that is not the way we do it in Fulcro, which beginners find confusing (I did). Here I explain why and what are the alternatives.
Still new to Fulcro? Make sure to check out my Minimalist Full-Stack Fulcro Tutorial!
Continue reading →
Code Study: Making code more functional
Having a pure function, what makes it more or less "functional" (as in "functional programming")? To me, "functional" includes favouring higher-level constructs over low-level "bit twiddling". Here I would like to demonstrate how I made one function more functional in this regard.
Continue reading →
Fulcro Troubleshooting Decision Tree
A decision tree to help you go from a problem to the most appropriate troubleshooting steps.
Continue reading →
My year 2021 in review
My professional year 2021 has been a year of Fulcro and Clojure. I have finally become a full-time Clojure developer and I have created a ton of resources for Fulcro beginners to ease and speed up their onboarding. To help them even more, while respecting the preciousness of time, I have started my company Holy Dev to provide mentoring and pair-programming to Fulcro learners. And I have written a few more essays about productivity and concepts such as simplicity on this blog.
Continue reading →
Awesome Babashka: Parse & produce HTML and SQLite
Babashka is a lightning-fast Clojure scripting tool with batteries included. It provided almost everything I needed to turn an AsciiDoctor document into a SQLite database and HTML in the format Dash - the offline documentation browser - requires to use it as a navigable, searchable "docset". While Babashka offers a lot out of the box, it can be further extended leveraging a number of available "pods" or extensions. This is a brief story of how I used Babashka to glue together Hickory, Selmer, and SQLite to make my html2dash.bb script.
Continue reading →
A light exploration of collaborative editing and synchronization algorithms
An important feature of Ardoq is that multiple users can edit the same model, i.e. a directed multi-graph. Changes from one user need to be propagated to the others and merged into their models. Collaborative editing (primarily of text) has reportedly been researched for 30 years and is still under active development. Here I share my field notes from learning about it briefly, without much tidying.
Continue reading →
What is simplicity in programming and why does it matter?
When I started with Clojure, I saw a language. Some people, when they look at it, they only see a weird syntax. It took me years to realize that in truth Clojure is a philosophy. The language embodies it, the ecosystem embraces it and grows from it, you the developer eventually soak it up.
The philosophy is simplicity - on a very profound level - and, to a lesser degree, ergonomics [1]. What do I mean by simplicity and ergonomics? Simplicity is about breaking things apart into their elementary constituents that are orthogonal to each other. Ergonomics is about making it possible and convenient to combine these elements in arbitrary, powerful ways. You end up with simple things that have single responsibility and that you can combine freely to suit your unique needs. These elements are simple but also generic and thus applicable in many situations and usable in many ways. This is crucial also for flexibility:
Continue reading →