kranfix / riverbloc

`flutter_bloc` implemented with `riverpod` instead of `provider`.
83 stars 17 forks source link

Migrate into bloc #11

Open chimon2000 opened 4 years ago

chimon2000 commented 4 years ago

I really love what you are doing here, as I have been exploring how to use bloc w/ Riverpod. I am wondering if it makes sense for this code to live inside of the bloc repository eventually. Tagging @felangel for his thoughts.

kranfix commented 4 years ago

Thanks for appreciate my work. I would like this code to live within the bloc repository (at least the useBloc hook function).

By the moment, flutter_hooks_bloc has the goal to reduce the nested widgets in the tree and flutter_hooks was a suitable tool for this.

I am also sending some PR to flutter_hooks to have a better information in the widget inspector. For example, with flutter_bloc, the widget tree looks like this:

but with the flutter_hooks_bloc it looks shorter:

This modification to the widget tree in the widget inspector will be released tomorrow (v0. 9.0). By the moment, this reduction of the widget tree is available for MultiBlocListener, but I'm working in MultiBlocProvider and MultiRepositoryProvider.

I hope @felangel is interested in these changes that I am making.

felangel commented 4 years ago

Hey all, I think there is definitely some interesting work being done but I'm still not entirely convinced that hooks is the direction we should be moving in. It's something that is being actively discussed and I will continue to monitor and experiment with the APIs as well but I don't think it makes sense to try to introduce hooks into the flutter_bloc package at this time.

The problem that hooks are solving in this case is providing an alternative to the builder pattern which is very prevalent throughout all of flutter. I would love to discuss some concrete use-cases for which hooks are better suited than builders in the context of the bloc library because generally speaking, there should be one bloc per feature so there should be very few cases where you need to nest BlocBuilders and BlocListeners (features should generally not depend on other features). In my experience having many nested BlocBuilders is usually a symptom of blocs that are data-driven or resource-driven and not feature-driven.

Would love to hear everyone's thoughts! Keep up the great work @kranfix and thanks @chimon2000 for starting this conversation! πŸ˜„

chimon2000 commented 4 years ago

@felangel I agree that hooks are a divisive topic, and I am actually more interested in the non-hooks version that @kranfix is working on vs. the hooks version (check out #12).

I think that the problems that riverpod by itself solves (type safety, simplified state composition, simplified testing) are extremely beneficial.

felangel commented 4 years ago

@chimon2000 yeah I definitely agree and it's something I'm happy to work towards but I am also hesitant about introducing a dependency on riverpod in it's current, experimental state. Eventually once it stabilizes and if the community begins to shift away from provider I think it would make sense but currently provider is still the most stable and widely used solution and I think forcing developers to use riverpod or having multiple DI solutions would be less beneficial. I'm happy to continue this conversation and continue experimenting in the meantime so that we are better prepared to make a shift as needed when everything has stabilized πŸ‘

chimon2000 commented 4 years ago

Totally fair @felangel. I expect this will be an open conversation dependent on when riverpod hits 1.0. I know Remi has mentioned the experimental tag will be dropped soon 🀞

rrousselGit commented 4 years ago

I already removed the experimental status actually. That doesn't mean it will have a 1.0, as that's a different topic. But besides minor changes for future features, it can be considered ""stable"" An article should come at some point during September.

Anyway, I'll be blunt: Do we really need BLoC with Riverpod? Genuinely wondering. As Cubit == StateNotifier, and there's an equivalent to all the other features (if not, make an issue ☺️)

chimon2000 commented 4 years ago

@rrousselGit I think that's a fair question. There are many similarities between the two. I am thinking specifically of users who may already be heavily invested in the bloc ecosystem, but want some of the convenience that riverpod provides.

Even in that case they may find, migrating from provider to riverpod not worth the hassle. I suppose the outcome of https://github.com/felangel/bloc/issues/1429 may affect this as well.

kranfix commented 4 years ago

@rrousselGit cubit has Changes and Bloc has Transitions (and also Changes because it extends Cubit). They allows to monitor the app easily. Outside of that, I don't see any significant difference with StateNotifier.

rrousselGit commented 4 years ago

Transitions are built directly inside Riverpod with ProviderScope.observers

kranfix commented 4 years ago

@rrousselGit The transitions with ProviderScope.observers are no enough useful as Transitions and Changes from bloc library. In bloc, you can have a global or a custom Change/Transition for each cubit/bloc.

Outside of that, I agree with StateNotifier == Cubit, but despite I like riverpod with StateNotifierProvider, I really need Change/Transition and that's the reason why I am working in riverbloc.

rrousselGit commented 4 years ago

In bloc, you can have a global or a custom Change/Transition for each cubit/bloc.

I'd appreciate if you could explain why ProviderObserver is not enough, with a concrete example

New features can be added to Riverpod if there is a need.

kranfix commented 4 years ago

Currently, each observer in ProviderScope.observers has the same execution. To make custom observers, each observer must ask all the time for the provider's runtimeType in order to customize the information. In addition, both Transition and Change give information about a current and previous state, while riverpod gives only the current provider's value.

Then I was thinking in opening an issue/PR with a pair of mixins from StateNotifier:
- mixin StateNotifierTransition\ on StateNotifier\
- mixin StateNotifierChange\ on StateNotifier\

And adding a static StateNotifier.observer similar to Bloc.observer.

rrousselGit commented 4 years ago

Currently, each observer in ProviderScope.observers has the same execution. To make custom observers, each observer must ask all the time for the provider's runtimeType in order to customize the information.

I don't understand what this means.

The previous value could be added to the update event, but I really don't understand what you are trying to do specifically. Some examples would be helpful.

tlvenn commented 3 years ago

Just stumble on this issue thanks to google, one thing that seems to be missing with the observer on riverpod side as outlined by @kranfix is the current state. There are many cases where it is super useful to have both the current and the new state (time travel, undo - redo, replay, etc...).

kranfix commented 3 years ago

@tlvenn I have been working to create a package with those complements, but time was no my friend in the last 4 weeks. But in December I will upload more stuff, including null-safety

tlvenn commented 3 years ago

yes no worry at all, i was merely trying to point out something to @rrousselGit that seemed to be lost in your conversation with him when you started to compare observers and actually the examples i gave would probably be doable if you only have the init value and the new values, that should be enough to build an history stack to replay, undo and the like but I somewhat remember seeing some use cases mainly with mobx when knowing the old value was actually quite handy.

tlvenn commented 3 years ago

Also it should be noted on comparing StateNotifier with Cubit that the biggest difference is that the former is based around listeners while the later is stream based and as such compose more naturally with blocs when you need them or other streams. Cubits also provides extension around persistence and behavior (redo/undo) with hydrated_bloc and replay_bloc.

This is not to say that one is better than the others, there are definitely different tradeoffs with both solutions. I personally prefer the ergonomic of Cubit over StateNotifier / ValueNotifier but that's just me.

pythonhubdev commented 3 years ago

Riverpod has now become stable and has a good amount of users and people have also started switching to riverpod because of it's ease thanks to @rrousselGit so now there could be a consideration to implement bloc with riverpod.

According to my thoughts.

maxzod commented 3 years ago

migrating Bloc FROM Provider to Riverpod will make no big changes to the Bloc Core API as far as i know it will only effect reading and disposing process inside the Bloc [ Builder , Listener , Consumer ] and remove the BlocProvider , and the MultiBlocProvider which will solve the context issues also Riverpod