TanStack Store for Applications #143
Replies: 5 comments 2 replies
-
|
In my job, I use tanstack store for our app instead of other solution that we use before, because we need a custom way to do things right for our app. But we also refactor other part of the app who needs global store to use tanstack store because we don't want to have many dependencies to do the same things. For me the main feature that will be usefull is :
And why we select tanstack store and not other solutions? For the question how to handle app needs and library needs for API design, I agree with the message in the PR, for a library needs I understand the design but for an app perspective if the api is simple to use it's better. Maybe something like the design is framework agnostic ok, usage inside library like this new Store, new Derived, new Effect, but for app create primitives, link to the framework specific and use under the hood the api for library part => useStore, useDerived, useEffect etc |
Beta Was this translation helpful? Give feedback.
-
|
From an application perspective, using zustand alongside tanstack query / router is quite popular. Similarly, jotai has a nice wrapper around query - https://github.com/jotaijs/jotai-tanstack-query tanstack store could be a potential solution that well integrates in this kind of usecase |
Beta Was this translation helpful? Give feedback.
-
|
Just updating this discussion with some suggestions that I put in a discord discussion. ContextI had a bit of a discussion over the last two days about what features would be the most useful in the code we write day to day. I think the TLDR; is that It really depends what Tanstack/store wants to be. Does it want to be a store that replaces Jotai/Zustand, or does it want to be a signal implementation. If it's the latter, then there are very few features you would expect to add to such a library, because it accomplishes the very minimal goal that it needs to accomplish while JavaScript doesn't support signals, and as I have mentioned historically, the only feature (from a react developer) that is missing in that regard is concurrent rendering - but this is something that I would expect will be added when it is supported in react itself. If the goal is to be an alternative to those other solution, but where the first principle is to provide framework agnostic tools like the rest of Tanstack, I think it's poised well to do so, because Tanstack already has such a large consumer base, and the ability to use it across frameworks makes it extremely powerful compared to other alternatives, because it's a transferrable skill, and will easily become a common tool if there is the desire. So if the goal is to be a "store", then personally there are some suggestions that come to mind, although I've excluded the obvious ones which I would've suggested just by opening up any other state manager docs and reading their features: Native support for persisting state to storage:This has come up quite a bit, because often when some state is global, you end up wanting to save it. I don't know how far you would want to take this, but being able to at least sync the state with local storage would be nice. Especially in small stores where an update is not expensive. Automatic subscriptions without need for selectorWhen your store is an object or tuple, it's pretty common to want to just access that state without a selector, but then you lose the fine grained reactivity because any store change will cause a re-render, for example: If there was some automatic mechanism (Proxy) that detected if it were an object or tuple and only subscribed to those changes, it would be a significant quality of life change. This would likely be similar to how tanstack query does this for useQuery results, but could automatically apply on any object that meets the requirements. This one is really important to me, because it's really hard to enforce the use of a selector in a company, or even convey this to junior developer. At my company we went so far as to make an Eslint rule for all of the router hooks since we were getting crazy re-renders of the app when using useSearch or useMatches, but even on a smaller scale, without the selector, the whole point of store is mute. Tanstack to me is known as one of the best libraries because of it's fantastic DX, and in query/router (and maybe table, not sure, haven't used), that translates to fantastic dev tools. I think that store is a prime candidate for this as well, because tracking global state is tedious, and knowing what changed can be pretty rough if it's used across application boundaries. This is also especially hard if you start to make more complex stores out of dependencies when Derived and Effect are used heavily. We don't have many cases of this, but if you ever get past a single layer of Derived (which is honestly bad practice anyway), it's a nightmare. Having good dev tools to see this as well as to "time-travel" state can be super useful. Some convenience helpers.Accept new state as well as callbackpassing a callback to setState is super annoying when you just want to set a brand new value (i.e. if the store is literally just a Boolean, or has 2-3 keys on an object). As a starting point, passing a new object directly instead of a callback function would be nice. To go a step further, we have a couple of utilities for typedSet functions, which gives you a typesafe way to set a single value on an object (which happens way too often across store/query). For example, being able to do // direct path to set value
setStoreAt(MyStore, "users.5.name", "ViewableGravy");
// with predicate
setStoreAtPredicate(MyStore, "users", (users) => {
return users.map((user) => ({
...user,
name: "ViewableGravy" // they are all me now
})
});Better ergonomics or utility hooks inside library contextWe use stores that are passed through contexts, or created within react a fair bit as a literal localized signal (rather than a "global" store), and have ended up making a couple of abstractions like useTanstackStore which returns Better documentationJust more documentation to support approaches for making signals and use cases, since I think a lot of people fail to understand why things like this exist. I had junior colleagues a few weeks and a personal project out of bootcamps that couldn't understand the difference between a state manager and context for a few months after joining, let along introducing the word "signal" and "fine grained reactivity" into their learning. Again, this has never been a point of store, but there isn't a single StackBlitz example of store to point to for reference. State ForkingThis isn't actually a "userland" suggestion, but is something that was suggested by tanner a while back in response to route transitions that I was having trouble with a year or so ago. TLDR; "state forking" at a store level. I can picture some really cool uses for this in general (although you may be able to accomplish the same thing using a derived store and simply storing the previous state) Better docsObviously since this is not meant for applications today, these are lacking, but just at a glance, there is an open PR which adds some basic but needed documentation to store. Just having something basic would be super useful for newcomers, and save me writing up a 3000 word notion doc on how to use this 😂 I also think maybe some mechanism for actually getting through PR's, since I know a couple of people have been hanging with no response for a while. Fair enough, I know everyone is very busy with epic projects like form or their own lives though, I don't have a solution to that - it's open source software after all. Schema supportIt's normally fully acceptable to rely on typescript types when setting the store, but sometimes it is not. Especially in our application where there is so much legacy code that is just completely un-typesafe and very easy to do something horribly wrong, being able to runtime validate that the type is good would be extremely handy because sending a signal out to all other subscribers would be nice. This also just helps with regressions in code bases where 100% type safety is but a pipe-dream (RIP 9000 type errors across 950 files :Crying: ) |
Beta Was this translation helpful? Give feedback.
-
|
A lot of what is mentioned here feels relevant for the Store, specifically in applications, especially because these are useful without tanstack query / sync too. |
Beta Was this translation helpful? Give feedback.
-
|
Need a devtool to view how store change, what actions has been triggered. Perhaps a simplest form like redux logger equivalent would be great |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
While working on #40 it became clear to me that
Storehas two different primary users:See, in libraries like TanStack Form/Table, it's really valuable to know when a
Derivedinstance orEffectis triggering a subscribe so we can know exactly when to remove them or add them back.For applications? Less important.
However, libraries also need to be framework agnostic where most applications are hooked into libraries.
So this is an open-ended question: How do we want to handle this discrepancy?
I don't just mean with these two APIs, either: We need to have a good backing philosophy for our projects to figure out how we want to treat apps that want to use TanStack Store vs libraries that need it.
Further, what value add does TanStack Start provide apps? What features are missing today that would be useful in TanStack Store as an app builder?
Let us know below 💖
Beta Was this translation helpful? Give feedback.
All reactions