[HN Gopher] Show HN: The simplest React state manager now at sta...
       ___________________________________________________________________
        
       Show HN: The simplest React state manager now at stable release
        
       Author : aenero
       Score  : 86 points
       Date   : 2021-04-20 09:20 UTC (13 hours ago)
        
 (HTM) web link (simpler-state.js.org)
 (TXT) w3m dump (simpler-state.js.org)
        
       | tomaszs wrote:
       | It looks promising. I wonder how it will play with TypeScript.
       | Would need to dig deeper. However the angle to make it simple is
       | great. No boilerplate code, unit testing as it should have always
       | been. Great work!
        
         | aenero wrote:
         | Happy to say that this also works well with TypeScript with
         | minimal explicit types required. My main goal is to maximize
         | the use of type inference. The documentation provides
         | TypeScript version of each example (outside of the TL;DR cheat
         | sheet), except in cases where TS version is the same as the JS
         | due to type inference. Even where there is TS version, the
         | difference from JS is minimal.
        
       | mewpmewp2 wrote:
       | Would it work with server side rendering?
       | 
       | Usually there would be a problem importing/defining things from
       | static files like that as this would be shared within the server
       | between instances of renderings.
        
         | munawwar wrote:
         | The simplicity goes away when supporting SSR. You have to
         | depend on multiple stores (one per request) being injected
         | "from the top" (e.g via Context Provider).
         | 
         | This is my take on the problem ->
         | https://github.com/Munawwar/react-global-states/tree/ssr
        
       | hliyan wrote:
       | Seems like the simplest state management API to wrap one's head
       | around that I've seen so far.
        
       | fastball wrote:
       | If you like this API but are already using Redux (or still want
       | to use Redux), I've found Rematch[1] to be a very productive
       | wrapper around redux that has a DX almost identical to this
       | library.
       | 
       | [1] https://rematchjs.org/
        
         | rtcoms wrote:
         | Have you compared this with other libraries like easy-
         | peasy(https://easy-peasy.vercel.app/) and
         | kea.js(https://kea.js.org/)
         | 
         | I've tried both of these and actually not fully able to decide
         | which one to pick. I'm inclined towards kea.js
        
       | Tajnymag wrote:
       | Looks great. The API reminds me of the new Vue 3 Composition API.
        
       | lf-non wrote:
       | I found effector[1] after I started looking around for a state
       | manager which:
       | 
       | 1. Either supported multiple stores or provides a way to
       | subscribe to individual branches (as opposed to the entire
       | store).
       | 
       | 2. Had an action/event abstraction similar to redux where
       | multiple branches (or multiple stores) could subscribe to the
       | same action and update independently (and without knowledge of
       | invoker).
       | 
       | I have been using it for some time and have had a good
       | experience.
       | 
       | The core is framework agnostic (with additional integrations for
       | react & vue).
       | 
       | I started used it with Svelte and its API matches the
       | expectations of Svelte stores so you can use it without needing
       | any additional integration, which was cool. Later I used it with
       | lit-element through a 5 line custom integration and that worked
       | pretty well too.
       | 
       | [1] https://github.com/effector/effector
        
       | tyingq wrote:
       | Curious if React developers feel like this sort of fragmentation
       | of what tools to use around React is fine, or if it's a pain
       | point for you.
        
         | chrisco255 wrote:
         | Fragmentation comes with open source. State management is
         | fragmented on the backend as well: PostgreSQL, MongoDB, Kafka,
         | Redis, Dynamo, Influx, etc...it's just that state management
         | fundamentally has different trade-offs based on how you
         | structure it (and may involve 1 or several of these).
         | 
         | If your app is simple, you don't really need a separate state-
         | management solution (just use the built-in React useState and
         | useReducer hooks). If it's complex, you have a choice to make,
         | but that's a fundamental issue with apps at scale and you have
         | to make those choices top to bottom.
        
           | vaughan wrote:
           | I feel like we are still waiting for someone to create a nice
           | multi-paradigm database blending everything we've learned in
           | the past 50 years, that can also run in the browser.
           | 
           | I see all state as a stream of events building a graph, then
           | we run queries on that graph. Then it's all about optimizing
           | the queries which we do.
           | 
           | We've kind of shoehorned our use cases into whatever dbs we
           | had available and have probably been overwhelmed by the speed
           | we needed to scale our cloud storage resulting in sub-optimal
           | solutions. Or maybe it's just wishful thinking that there
           | will exist a db to do it all.
        
       | panzerklein wrote:
       | Looks like it's based on the same idea as jotai[1]
       | 
       | [1] https://github.com/pmndrs/jotai
        
       | aerovistae wrote:
       | I haven't tried this one, but for what it's worth, if you're
       | looking for a simple state manager, I LOOOOOOOOOVE Pullstate.js.
       | I've been using it for a reasonably complex frontend and it's
       | just excellent, an absolute breeze to work with. For reference,
       | I'm the type of person who appreciates the power of redux but
       | views it as conceptually overcomplicated to the detriment of the
       | developer experience-- I felt it was overhyped and added limited
       | value relative to the cost of its complexity. (Not that it's
       | _that_ complex, but more than a state manager needs to be.)
       | 
       | Pullstate is extremely simple but just works perfectly.
        
         | richeyryan wrote:
         | That looks really good. I like how the hook is built into the
         | store API.
         | 
         | My problem with a lot of these simple state managers is they
         | often just stop short of handling asynchronous state. I think
         | it should pretty much be mandatory to handle pending and error
         | states on promises for state manager nowadays. Pullstate's
         | Async Actions look pretty good for that.
         | 
         | I've been using Effector a lot recently because it has just a
         | bit more power in managing the interactions between stores and
         | events but if I needed something more straightforward Pullstate
         | would be good. Thanks for the tip!
        
       | xyclos wrote:
       | reminds me of mobx (which I find very simple). an entity is just
       | like an observable, no?
        
         | yetanotherjosh wrote:
         | I'm an avid user of mobx and yes, this is similar, but no where
         | near as powerful, and much less magical. For example, in no
         | particular order:
         | 
         | * mobx is smart enough to know when only one property of a
         | complex object has changed and that that component depends only
         | on that property. So you can have complex state objects, and if
         | your component only uses property X of said object, it only re-
         | renders if X changes but not Y.
         | 
         | * mobx allows you to compose observables - any observable can
         | reference the value of any other observable and if that second
         | observable changes, the listeners for the first observable will
         | re-render, etc. This means state can depend on other state, and
         | everything updates correctly. For example, if you have a store
         | that fetches profile data for the auth user, and the auth user
         | id changes due to login or logout, the profile data store can
         | trigger a refetch, all this happening outside the react
         | component tree, then finally the correct components re-render.
         | 
         | * mobx works on it own and is agnostic to framework
         | (react/vue/etc) and is integrated via binding libraries for
         | each framework.
         | 
         | * mobx provides quite a few different kinds of observables with
         | different behaviors (shallow maps, lists, etc)
         | 
         | * mobx allows you to declare arbitrary reactions that run
         | automatically when state changes, whereas this library here
         | really just re-renders components when state changes.
         | 
         | * With mobx you don't even have to say which things in your
         | component use observables - you just wrap your component in
         | observer(), and any time it references an observable, mobx
         | tracks it and will re-render the component if the observable
         | changes. Whereas here you need explicitly hooks for each state
         | atom.
         | 
         | There are many more differences, in every case mobx does more.
         | So mobx is a far more complex and powerful system, whereas this
         | is a simpler system that extends useState() hooks with objects
         | that live outside the component. Which is not a value
         | judgement, use the simplest tool that meets your needs.
        
           | FlashBlaze wrote:
           | Have been using mobx recently and wrapping your component in
           | observer() and seeing it update when the observable changes,
           | feels truly amazing.
        
       | robovirtuoso wrote:
       | After lots of tweaks based on the valuable feedback from the
       | community, SimpleR State is finally at its first official stable
       | release v1.0.0.
       | 
       | Big thanks go to the great people that contributed to this effort
       | to bring it to Production grade. I can now confidently call it
       | the "simplest" out there. Mission accomplished.
        
       | BenoitP wrote:
       | Very nice!
       | 
       | I've been prototyping something server-side in the style of the
       | SQL Kappa architecture: facts on immutable logs, possibly keyed
       | (and compactable by key), and SQL materialized views streaming
       | the updates with Flink. And I'm in search of a React state
       | manager in that philosophy.
       | 
       | Rows are sent to each client requesting a feed of them:
       | INSERT INTO user_orders_total_feed(user_id, data)         SELECT
       | uo.user_id,           SUM(o.price) total         FROM user_order
       | uo         JOIN order o ON uo.user_id = o.user_id         JOIN
       | user_live_subscription uls ON uo.user_id = uls.user_id
       | GROUP BY uo.user_id         WHERE uls.subscription_topic =
       | 'orders_total'
       | 
       | But: maybe you want all the orders in the UI and do the
       | aggregation client-side, to have all orders alongside the total.
       | You could move the aggregation to the client side. And it would
       | be great to have the same data language than on the server (so
       | that business rule expression is the same).
       | 
       | In that case, a React Hook library like SimpleR State could
       | aggregate in SQL the sum and update the view reactively. It would
       | look like:                   const TotalView = () => {
       | const view = state.view('SELECT SUM(price) total FROM
       | order_feed');                    return (             <>
       | <div>{view.total}</div>             </>           )         }
       | 
       | I don't think that would be easy to do; but I think there is a
       | market for it: The business folks doing no-code+SQL client-side,
       | and they would sometimes ask through proper channels for a query
       | to be computed globally server-side or be brought client-side.
        
         | vaughan wrote:
         | I think SQL on the frontend is a big opportunity. It's a
         | powerful declarative language that matches nicely to React.
         | 
         | Every component's data requirements are essentially an SQL
         | query, and a lot of client-state could probably be represented
         | in further SQL queries (filtering, aggregation).
         | 
         | Doing joins makes things much more consistent too when the same
         | entities are referenced in multiple places in the UI.
         | 
         | Just like React works declaratively by re-rendering the virtual
         | dom, wouldn't it be great if we just re-ran a declarative query
         | for the data too?
         | 
         | Kind of like Redux (global state) I guess but a relational
         | model version.
        
         | aenero wrote:
         | Although this is not provided by SimpleR State out of the box,
         | the library makes it easy to implement a "selector" function
         | that accepts an SQL query, and pass this selector to the entity
         | hook. This SQL query syntax in React can well be a library on
         | its own, I suppose.
        
           | BenoitP wrote:
           | Would that be the transform function from here [1]?
           | 
           | I do agree too that this definitely should be a library on
           | its own.
           | 
           | Anyway thanks for your work; I'll definitely check SimpleR in
           | my project.
           | 
           | [1] https://github.com/arnelenero/simpler-
           | state/blob/f6336817c9e...
        
             | aenero wrote:
             | Yes, I called it "transform function" in the documentation
             | to reflect the more general functionality that also
             | includes computed values, apart from selection ("picking"
             | properties).
             | 
             | Thanks for your encouraging feedback.
        
       | garritfra wrote:
       | IMHO, since react hooks hit the market, state management
       | libraries became kind of obsolete.
        
         | jeremy_k wrote:
         | We tried this approach and have attempted to bend React Context
         | to our need, but it feels like its gotten pretty hacky. Are you
         | only using component state and Context or what is your
         | approach?
        
           | steve_adams_86 wrote:
           | Not who you asked, but: We use useContextSelector to ease
           | context rendering redundantly and to make it clearer what a
           | component uses within a context.
           | 
           | It isn't native to react, but it appears it will be in a
           | similar form in the future.
           | 
           | It has been a joy to use so far. Having server side state
           | working so seamlessly with the client is a great feature for
           | us.
        
       | jokethrowaway wrote:
       | There are tons of small simple state management solutions for
       | react coming from all the people who hate redux's complexity and
       | lack of async actions
       | 
       | Well done for getting some community traction!
        
         | acemarke wrote:
         | Note that our official Redux Toolkit package specifically
         | resolves most of the concerns people have expressed over the
         | years about "Redux boilerplate", including drastically
         | simplifying writing reducers and actions and including support
         | for thunks out of the box. RTK is now the standard approach for
         | writing Redux logic:
         | 
         | - https://redux-toolkit.js.org
         | 
         | - https://redux.js.org/tutorials/fundamentals/part-8-modern-
         | re...
        
       | ezekg wrote:
       | I still don't think I'll ever use something other than this:
       | https://formidable.com/blog/2021/stores-no-context-api/.
       | 
       | Literally as simple as it gets.
        
       | mhalle wrote:
       | For another comparison, there's valtio that I learned about from
       | a previous HN discussion: https://github.com/pmndrs/valtio
        
       | thunderbong wrote:
       | This looks fantastic! After twisting my brains over redux, this
       | looks like a breeze to work with!
        
       | danlugo92 wrote:
       | Usage feels very similar to redux when using redux toolkit, and
       | the latter comes with a more mature ecosystem.
       | 
       | There was also nothing about streams and such that you would
       | normally handle with redux-observable or redux-saga.
       | 
       | One of the super powers of redux+saga is being able to listen to
       | every state update (and act according to that), this doesn't seem
       | to be possible (unless you make a super entity I suppose?).
        
         | wayneftw wrote:
         | A quick glance at the documentation showed that you can write
         | plug-ins to do such things as listening to all state changes
         | (unless I misunderstood something). See the logging plugin
         | example.
         | 
         | Without a Chrome dev tools extension though I don't think I
         | could leave redux just yet.
        
           | aenero wrote:
           | Happy to hint that there is an upcoming plug-in to support
           | Redux DevTools too. Soon.
        
       ___________________________________________________________________
       (page generated 2021-04-20 23:02 UTC)