DEV Community

Cover image for State Management with a Single Line of Code

State Management with a Single Line of Code

Ankit Singh on November 02, 2020

If you're like me and feel that there has to be an easier way of state-management, then you'd like what ActiveJS can do for you. I feel like I'm s...
Collapse
 
zalithka profile image
Andre Greeff

Careful Ankit, you might just make people actually start enjoying state management if you carry on like this.. (:

All jokes aside, this is a very nicely written article though, thanks for the ActiveJS intro! :D

Collapse
 
dabalyan profile image
Ankit Singh

Hey Andre, wouldn't that be something ;)

thank you :)
I'm just glad that I didn't mess up

Collapse
 
avkonst profile image
Andrey

Have a look into Hookstate hookstate.js.org. it is truly one line state management, but covers a lot of use cases and takes care of rerendering performance without extra effort from a programmer

Collapse
 
robvirtuoso profile image
robvirtuoso • Edited

I'm just keeping track of how this guy shamelessly plugs his HookState library seemingly everywhere. Promoting it is quite ok, but comparing it this way is not... I mean, does it have to be a competition who has the best library??? I find this self-promotion quite distasteful.

Collapse
 
avkonst profile image
Andrey

Could you please do a favor for everybody on the internet and educate all others, who post comments pointing out to alternatives?

Thread Thread
 
robvirtuoso profile image
robvirtuoso • Edited

That would be easy because not a lot of them point to their OWN library as the "alternative". And much less would blatantly even imply that their library is the better one.

Your library is not bad at all, so just be careful not to leave a bad taste in people's mouths with your posts. It won't be doing your library any favor.

Thread Thread
 
avkonst profile image
Andrey

At least I am honest and publish it from my own single account and put a disclaimer. It would be quite naive to believe that "promotions" (not only about this category of libs) are done by other independent people if they are not done from "an owner's account".

Thread Thread
 
robvirtuoso profile image
robvirtuoso • Edited

I'm not trying to antagonize you. I just hate the idea that independent open source contributors like you will get a bad reputation due to their posts like this. I find publishing open source libs a noble thing to do, especially for people who don't earn a dime from it. You seem like you belong to this category, so I appreciate your efforts. I actually help promote work of libs that I personally use, as a way of giving back to the author/maintainer. If your posts triggered a bad reaction from me, it may happen with others too. So again I wouldn't wish you that misfortune.

You may not be asking for advice from me, but if it was me I would not want people thinking that I'm doing this to compete with the big guys (Redux, Recoil, etc.) which are backed by a big corporation and fanboys... And nor would I ever say that my lib is superior to another , popular or new one.... open source is not a popularity contest after all. As long as a number of people actually use your library, i.e. it is helping some folks out there, it means you already are doing a good job.

Collapse
 
dabalyan profile image
Ankit Singh

hey Andrey, kudos for the amazing things you're doing with hookstate.

I remember stumbling on hookstate at some time when I was searching for alternatives to reducer based state managers, I really liked the hookstate. But as I don't have much experience or use case for React, I had to move on. I guess that's one of the differences that sets ActiveJS apart, it can be used with any framework, or even without a framework as well.

Collapse
 
darlantc profile image
Darlan Tódero ten Caten

Your first article is just... awesome! Well done man!

About your library, I'm very impressed with so much love you put into it: beautiful website, incredible documentation with examples to easily verify how it works.

I'm very happy with MobX at the moment in my projects but I certainly will try your library in future projects as I really love how simple it is.

Collapse
 
dabalyan profile image
Ankit Singh

thank you :)

I didn't have much else to do, but still it wasn't easy, thanks for noticing :)

Making it simple was the objective, "Pragmatic not Idealistic" is the motto.
Glad that you find it that way :)

Collapse
 
rschneider94 profile image
Rodrigo Schneider

Hey Ankit! Really nice article, thanks for sharing this! Wish I knew this a few months ago.

Just a little correction: in the Type-Safe heading you typed disptach instead of dispatch. It's not a big deal, but just to let you know in case you didn't notice that.

Have a great day and I'm already following you! :)

Collapse
 
dabalyan profile image
Ankit Singh

hey Rodrigo,
my pleasure, and I wish could have finished it sooner :)

damn, didn't know I was dyslexic, thanks for letting me know, jk ;)
fixed it

you too, thank you :)

Collapse
 
fly profile image
joon • Edited

So yesterday I was feeling fed up with setting up redux and realizing
that the whole process was going to be a pain when I just needed simple
global state functionality.
Instead of the obvious 'searching for a good alternative' I just went and wrote a single file version instead.

gist.github.com/fl-y/dc500f0841fd1...

Quite pleased with myself,
on my way to work while scrolling through dev.to I noticed this gem.
I feel like this is pretty much what my prototype would have become with a LOT of hard work(But probably multitudes worse).
I sincerely thank you for sharing this project.

Going to try this out straight away :)

Collapse
 
pclundaahl profile image
Patrick Charles-Lundaahl

Adding on to my last comment, I'd just like to say that, while I may not may not use this myself (I only really do front-end development at work, and that's almost exclusively limited to modifying existing apps), I think this is just a really cool project.

Regardless of current bundle size, etc., having more people thinking about state management and trying to improve it just strikes me as a really good thing.

Collapse
 
dabalyan profile image
Ankit Singh

It's okay if you can't use it, the encouraging words are good enough :)

Regarding the bundle size, I guess there's some confusion, the 8kB is the complete library bundled together (without tree-shaking) along with RxJS dependencies. If you're using a module bundler or already using RxJS in your project, the final build size contribution will be much lower.

Collapse
 
kgignatyev profile image
Konstantin Ignatyev

Interesting idea, but 'working' assignments which do nothing is very bad idea.

newValue.c = 'hehe' // works, but

dataUnit.value() // still {c: 3}

that is not acceptable IMO, must throw exception

Collapse
 
dabalyan profile image
Ankit Singh

thanks :)

There's an option to enable that behavior as well, but it's only recommended to be used in development mode, see checkImmutability flag in docs.activejs.dev/guides/developme...

Collapse
 
kgignatyev profile image
Konstantin Ignatyev

Well, I think that should be the only behavior.

Thread Thread
 
dabalyan profile image
Ankit Singh

ActiveJS is configured with most sensible defaults, and gives you the ability to configure it in your own way.

You can keep the checkImmutability check on in the production as well, but it's not something that ActiveJS or people much smarter than me recommend :)

Collapse
 
inlagny profile image
MadeInLagny

Nice work ! Since you subscribe to variables and not store, how do you deal with this in a component-based app ? Do you need to susbscribe to all required values in each component ?

Collapse
 
dabalyan profile image
Ankit Singh • Edited

hey MadeInLagny, thanks :)

The general idea is that you access the Units directly, wherever required, however if two Units make more sense together, you can keep them separate but get their combined value by grouping them together using a Cluster.

// two Units
export const unit1 = new DictUnit({initialValue: {a: 1}});
export const unit2 = new DictUnit({initialValue: {b: 2}});
// grouped together
export const myGroup = new Cluster({unit1, unit2}) // using shorthand notation
// subscribe for reactive grouped value access
myGroup.subscribe(groupedValue => console.log(groupedValue))
// you'll see {unit1: {a: 1}, unit2: {b: 2}} in the console immediately and 
// it'll also log any future values
Enter fullscreen mode Exit fullscreen mode
Collapse
 
inlagny profile image
MadeInLagny

But how do you access myGroup value in a component where it was not initialised ?

Thread Thread
 
dabalyan profile image
Ankit Singh • Edited

ahh I see, do you mean how to share a Unit or Cluster with multiple components?

you initialize them and export them from a separate file, then you can access them wherever needed, with a simple/direct import.

Collapse
 
tojacob profile image
Jacob Samuel G.

I love that you use rxjs. I was going to write something similar (not so good) for my next project. It may be irrelevant, but what happens when LocalStorage is not available? Personally I use "Persistore" to handle storage, as I am confident in the falls back it offers. I haven't checked the Active source code yet. Do you think it could support plugins to handle persistence?

Collapse
 
dabalyan profile image
Ankit Singh • Edited

thanks :)

are you referring to usage in NodeJS environment? Because all modern browsers have localStorage afaik. And if it's not available then plugins won't be able to help there.

that being said, yes you can replace the storage used for persistence, anything that implements the Storage developer.mozilla.org/en-US/docs/W... interface can be used, see docs.activejs.dev/guides/persistence.

Collapse
 
jonrandy profile image
Jon Randy 🎖️

One line... plus 1.64MB to import the library, and likely add dependencies on top of that. Ludicrous

Collapse
 
dabalyan profile image
Ankit Singh

only 8kB gzipped, and it's tree-shakeable too, that's what would go to production, not all the 1.64MBs of documentation, typings, and unpacked code.

Collapse
 
aisone profile image
Aaron Gong

Thank you for the good effort.

Yes it is 8KB gzip, will also need to add 11kb for rxjs (but this is ok for those who have use case for rxjs).

The next step is to make the library have as little dependencies as possible. One that does not have breaking changes or at least are easily manageable.

Thread Thread
 
dabalyan profile image
Ankit Singh

my pleasure :)

not quite correct, those 8kBs include all the RxJS dependencies that ActiveJS has, and 8kBs are for projects that are going to use ActiveJS without a module bundler, the target use case of ActiveJS is going to be modern Web-Apps built with modern frameworks, all of them have a module bundler like webpack, to eliminate any unused/dead-code from the bundle, see en.wikipedia.org/wiki/Tree_shaking.

Dependency on RxJS is a feature not a bug ;)
Since the ActiveJS Units extend RxJS' Observable class, it gives you the possibility to use all the myriads of RxJS operators.

Collapse
 
darlantc profile image
Darlan Tódero ten Caten

Why so angry man? You just read the title and get straight here to comment without taking the time to analyze the work of the author?

Collapse
 
ckapilla profile image
Chris Kapilla

very impressive design -- I will investigate it further.

Collapse
 
pclundaahl profile image
Patrick Charles-Lundaahl

That's one heck of a first article! Bravo!

Collapse
 
dabalyan profile image
Ankit Singh

this means a lot, thank you :)

Collapse
 
damianesteban profile image
Damian Esteban

This is an impressive library. Thanks for the share :).

Collapse
 
anuraghazra profile image
Anurag Hazra

This looks promising

Collapse
 
shirkan profile image
Liran Cohen

Well done

Collapse
 
emex4gman profile image
Ibebugwu Chukwuemeka

This is real nice. Probably try it out in my next project

Collapse
 
srikanth597 profile image
srikanth597

Interesting, glad I found this.

Collapse
 
yurieastwood profile image
Yuri Eastwood

Woah, nice article! I was even more astonished when I read was your first! hehe
Didn't knew about ActiveJS, it seems really interesting!

Keep up the good work! Kudos!

Collapse
 
jvas28 profile image
Julio Vasconez Yulan

Amazing work man!

Collapse
 
dabalyan profile image
Ankit Singh

hey Julio, what a surprise, great to see you here :)

thanks :)

Collapse
 
hakimio profile image
Tomas Rimkus

Why not just use Akita? It's really simple and works well with vanilla JS -> datorama.github.io/akita/docs/addi...

Collapse
 
kashkovsky profile image
Denis Kashkovsky

What about github.com/grammarly/focal ? In addiction Focal can lift any react component to receive props as observables.

Collapse
 
dabalyan profile image
Ankit Singh

Never heard about it, just checked it out, "focal" looks great, it's a very similar approach I must say. From what I could gather, it only works with React, ActiveJS has no such affiliation as of yet, that can be a good or bad thing depending on who you ask. We don't have any plans to create special bindings for any framework, but it's something that we can think about. Thanks for sharing this.