-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request for the documentation of a typical ViewModel/Controller implementation #10
Comments
Hi @Kypsis , the way I typically do it is by using a logic file to represent the ViewModel / controller layer. Using Decremental counter as an example, if we change Another example would be the DartPad. If using bloc, I would probably put Let me know what you think. If you are happy with these, I can make the doc more obvious. As for .value getter, did you use mobx or getx? To implement that, I guess we need some kind of global state to track which observable is under recreation. You can check out the "Using subscription" section in my article here. I don't feel creator could/should do that, but happy to hear what is in your mind. |
From my pov the bigger issue is namespaces. I've been to React/RN projects where these atomic state enablers (useState/proxy/create/whatever) usually mean you have singular values bound to singular identifier. And unless you enforce a very strict naming schema it becomes very messy fast, especially with complex interconnected domains. So I guess my question is using an example from Valtio from JS land: https://github.com/pmndrs/valtio/wiki/How-to-organize-actions If we can do the first example and probably second, how can we achieve the 5th result (last one with class, 3rd and 4th are undoable since Dart has no anonymous objects like JS or Kotlin). And when taking the news example then again from my pov it's better dx if I can do news.loading and news.fetchMore. Or more precisely having the state field and action available from same origin. If I think about it more I feel as there is a way to achieve hook like usability but I can't quite put the lego bricks together in my head. |
If the namespace is a concern, how about just wrapping them into a class and using static variables?
If you don't like static variables, then you can make it plain variables and then create an instance:
In either approach, it is just how to organize Dart code. There is no magic behind it. |
Though I might miss something about |
Hah the static field one is brilliantly simple way to address namespace. It very well exemplifies how it is sometimes very hard to get out of the mindset that everything has to be instantiated when doing OOP. For the second example, how do you optimally watch for say the loading or data value in Watcher. At the moment I have final news = Creator.value(News());
...
Watcher((context, ref, _) => Text(ref.read(news.map((state) => ref.watch(state.data)[0])))) which seems kinda clunky way to access the field and have it rebuild the widget. This is the use-case I meant when I said it would be nice to have .value getter eg |
The example above, I use a global variable If you really want to put that in the graph, use the graph as a service locator.
|
Now I see where I went wrong and why I asked hopefully not too obvious questions. I was trying to do: Widget build(BuildContext context) {
final levelStateCreator =
Creator((ref) => LevelState(ref, onWin: _playerWon, goal: widget.level.difficulty));
...
Watcher((context, ref, child) {
return Slider(
label: 'Level Progress',
autofocus: true,
value: ref.watch(ref.read(levelStateCreator).progress) / 100,
onChanged: (value) => ref.read(levelStateCreator).setProgress((value * 100).round()),
onChangeEnd: (value) => ref.read(levelStateCreator).evaluate(),
);
}),
... and wondering why on earth is the slider not updating. Adding keepAlive fixed it. There is also a subtle "bug" with using the class version and instantiating it that way. On route change the slider resets to 0. That bug is not present when using the non service locator pattern variants. Overall the issues I've had so far seems to be of the pbkac kind. I see great potential for this library as it is I think the only state management one for Flutter that truly allows for bottom-up state management (as described in this article: https://frontendmastery.com/posts/the-new-wave-of-react-state-management/). I think with some effort one could create a solution using Creator that covers the use-cases that the hugely popular react_query solves in the React land and other ways to effectively create black-box abstractions to cover repetitive use-cases (looking at you ddd with bloc where you can potentially write over 1k lines and touch/create 10s of files just for a simple API call over and over again). Maybe the only real suggestion to give would be to align the documentation with what Zustand, Recoil, Jotai and Valtio in JS land are doing as it seems Creator can potentially fill the same problem space niche in Flutter. |
As for the example, it seems you put a creator variable inside the build function. If that's the case, be really careful and read the https://github.com/liangxianzhe/creator#creator-equality section. As for the bottom-up, I'm not so sure how to improve doc since I'm not familiar with all these :) If you have more actionable ideas, let me know. Though from what I know, vuejs and solidjs also work similarly, meaning they also use a fine-grain reactive model. |
As the title says would like to have an official example how to implement a typical view model/controller implementation. Basically Creator version of this documentation: https://riverpod.dev/docs/providers/state_notifier_provider/
This is to facilitate easier transition (by having reference documentation) for people wishing to refactor from other state management solutions (eg bloc).
Aside: I keep automatically trying to access creator via a non existing .value getter as if it was a hook or observable.
The text was updated successfully, but these errors were encountered: