Finally, files generated with kea-typegen will automatically import any types they can, and add the rest as type arguments
for kea<logicType<LocalType, LocalUser>>
You just need to add types to your actions and reducers.
import{Blog}from'./blog' import{ logicType }from'./logicType' exportconstLocalType='YES'|'NO' const logic =kea<logicType<LocalType>>({// ๐๐ฆ managed automatically by typegen actions:{ openBlog:(id:number, blog?:Blog)=>({ id, blog }),// ๐ add types here closeBlog:(answer:LocalType)=>({ answer }), }, reducers:{ blogId:[ nullasnumber|null,// ๐ null now, but sometimes a number ๐ { openBlog:(_,{ id })=> id, closeBlog:()=>null, // use `actionTypes` instead of `actions` [funLogic.actionTypes.randomBlogPage]:()=>4,// chosen by a fair dice roll }, ], }, listeners:()=>({ closeBlog:({ answer })=>{// no types needed here console.log(answer) } }) })
Back in 2015, shortly after learning about React and Redux, I fell in love with the functional programming paradigms behind them because of what they enabled.
By following a few principles of immutability and purity, React frontends were generally better written, stabler and easier to debug, compared to contemporary alternatives such as Ember or Angular.
Having seen what a bit of functional programming did to JavaScript, I started looking into Clojure, the most popular functional language at the time, and into ClojureScript frontend frameworks: reagent, quiescent, om, om.next, and re-frame. Now there's also fulcro that wasn't around back then.
What stood out was how they all handled application state.
They all had developed at least three globally isolated layers:
// obvious pseudocode asyncfunctionrenderApp(){ while(awaitwaitForChanges()){ // gather the input (check the url and call APIs) const input =awaitgetInputFromURLAndAPIs(window) // normalize that to an intermediary app state const appState =convertInputToApplicationState(input) // create HTML out of that intermediary state const html =convertApplicationStateToHTML(appState) render(html) } }
No framework skipped the application state step. Nobody did this:
asyncfunctionrenderApp(){ while(awaitwaitForChanges()){ // gather the input (check the url and call APIs) const input =awaitgetInputFromURLAndAPIs(window) // create HTML out of that input const html =convertInputToHTML(input) render(html) } }
Yet that's exactly what you're doing when you store application state in React components.
All these frameworks reached the conclusion that the best way to convert API responses to DOM nodes was to first convert them to an intermediary representation: the global application state.
These three layers (input, data and view) have overlapping, yet separate and parallel hierarchies:
The structure of your input data is different from the structure of your application state, which is different from the structure of your DOM nodes.
I think this is a clear step backwards for maintainability.
Wild speculation
This is pure speculation, but I think this is why Suspense is still considered experimental in 2021, despite having been in development for over 3 years. It's just not that easy to blend the data and view layers in a way that makes everyone happy. Hence things keep being pushed til "when it's done".
I think it's time for a change. It's time for a paradigm shift.
It's time for a revolution in data-first frontend frameworks, which relegate React to what it does best: rendering and diffing DOM nodes. Values in, actions out. No useState. No useEffect.
In practice this means adopting a data layer as the core of your application.
It means going from:
Frontend > React > [state management library of choice]
Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
In all my years of programming I have yet to see an exception to this rule. On the contrary, teaching this to junior developers has proven to be the single most impactful thing in improving their code quality.
From that moment forward, I would see this everywhere. If ever I felt like my program was getting too complicated or hard to read, it was almost always a data structure problem. Since then, every time I've been humbled by another programmer's code, it hasn't been by clever tricks or algorithms. It has always been by their ingenious insight into how their program's data ought to be organized.
It's time for a change. It's time for a paradigm shift. It's time for a revolution in data-first frontend frameworks that control the view layer and not the other way around.
Since you're reading this on the Kea blog, I'm obviously biased as to what's the best data layer for frontend developers. Suggesting alternatives is made even more complicated by the fact that most other tools position themselves as "state management" libraries, at the mercy of React.
Kea is one of the few frameworks for managing the complete lifecycle of your data. It uses React as the view layer and integrates nicely with the existing Redux ecosystem.
Go check it out and then start writing webapps the way they were meant to be written: data first.