-
Notifications
You must be signed in to change notification settings - Fork 58
Is this a duplicate of "provider"? #3
Comments
Hey @rrousselGit, This package originated in Fuchsia and has been used by Google for some time (along with the previous incarnation of it, I don't think it's a duplicate with your package. Yours is more feature-ful and has different ideas. Sorry about the naming closeness. I guess great minds (you & @jiaeric) think alike. We did not know about |
I don't particularly mind the name conflict. I'm more concerned about the conceptual conflict. Overall I think:
As such Ironically I'm not a fan of the API of It pushes bad practices that even the readme do:
Provide.stream<Counter>(context)
.where((counter) => counter.value % 2 == 0), This little snippet causes an issue because we're effectively creating a new stream on every build of
@override
Widget build(BuildContext context) {
// Gets the Counter from the nearest ProviderNode that contains a Counter.
// This does not cause this widget to rebuild when the counter changes.
final currentCounter = Provide.value<Counter>(context); That one cheats the widgets system by not listening to Flutter did a great job at preventing mistakes with
The idea of exposing multiple providers at once is cool. But by not being a widget, its API is misleading. We are easily tempted to do: class Foo extends StatelessWidget {
const Foo({Key key, this.child}): super(key: key);
final Widget child;
@override
Widget build(BuildContext context) {
return ProviderNode(
providers: Providers()
..provide(Provider.function((context) => Counter(0))),
child: child,
);
}
} Again, this looks innocent. But if
I'm not saying that we should use By having Google back up a solution that looks that unsafe, I fear that instead of solving problems this will increase them. |
Hi Remi, Let me read through and think about your concerns for a bit, I need to mull them over to make sure my thoughts make sense. I want to make sure I address the meat of your concerns, and not just gloss them over. I think from an approach perspective, the biggest difference between provide and provider is that provide isn't using InheritedWidget directly, and instead uses a container class. You've correctly surmised that one of the big benefits is that it supports many providers at once. But the main reason I went with that option is to allow subtypes and interfaces. So you can create a Provider that returns something that implements T. As I found out the hard way when refactoring code, InheritFromWidgetOfExactType doesn't allow this. Provide.stream - this indeed creates a new filtered stream each time. I'm not sure what the concern about that is though - is it that people will hang on to old streams? Provide.value - this was intentionally created to not rebuild, because we found we were having some performance problems when too many things were rebuilding on each change. As such, we needed a way to obtain injected values without creating a rebuild. |
I think you have a very good point about the Providers part; it seems pretty easy to shoot yourself in the foot there. |
Hello 😄 I hope that I do not sounds harsh or trying to sell my product. From a recent discussion with @filiph, it seems that the goal for this library is to be the standard for newcomers.
That's one of the reasons For example, what would be written as: ProviderNode(
providers: Providers()
..provide(Provider.value(42)
..provide(Provider.function((context) => Counter(0))),
child: child,
); becomes: MultiProvider(
providers: [
Provider(value: 42),
StatefulProvider(valueBuilder: (context) => Counter(0)),
],
child: child,
) On the verbosity/readability aspects, these two are almost identical (although The difference is that
Sorry, I do not understand what you're saying here. From my understanding, this is possible: class Foo {}
class Bar implements Foo {}
Provider<Foo>(
value: Bar(),
child: ...
); But I'm likely misunderstanding the problem.
If possible, it probably shouldn't be the default behavior (although will probably be difficult with the current API). As an example, both
These do the same thing, but are not the default behavior. In that situation, a mistake from the developer doesn't do any harm. The opposite is different. It's easy to forget to listen (no warning/error), and such mistake can break the application. |
Your feedback is very appreciated! As you said, anything that makes the community better is better. I think the stream issue wouldn't be an issue if initialized. Though as you said, this isn't a problem with your way of doing things. Re: downcasting - We had a bunch of implemented inheritedWidgets that were writing their own .of(foo) functions. You're right that Provider also solves this problem (as well as scopedModel now it seems, which has changed from the old version I used at the time) I'm reading through the provider, and your additional comments. Might be easier to do a chat or video chat and loop back here |
Hey all, just thought I'd pop in here and let ya know what I'm thinking from these discussions:
Overall, I think this is a great discussion to have. |
Ok, I just wanted to give a quick update.
I regret that I didn't have a better look at The upside is that we can have this discussion, over concrete code. There's more discussion to be had with the Flutter team, and the Google teams that use Flutter. I expect to have more to say on this thread sometime next week. In the meantime, I will add a notice to the README so that people don't prematurely start using the package just because it's "official" (i.e. from Google). |
I would like to see |
I said I'd update this thread "next week" and then it's next month. Sorry about that. We're in active discussion with @rrousselGit. He's building the next version of I also added a note to https://pub.dartlang.org/packages/provide that directs people towards this discussion. Cheers! |
Ok, time to make a difficult decision. We still like So as not to confuse matters, and because there is not likely to be further development of To be clear, the package will always be available at https://pub.dev/packages/provide — pub doesn't allow packages to "disappear". But it won't be updated. I have looked at all the 33 forks of this project to see if there's active development in any of them. It seems there isn't. If I missed something, please reach out to me. (Just comment on this thread.) Apologies for open sourcing something that didn't pan out in the end. I personally think it's better for everyone this way, as we now have a very strong community-initiated package. I'm just sorry for the confusion. |
See google#3 (comment) for more context.
👋 maintainer of provider here
It seems that this library aims at doing exactly what mine does: a set of generic providers to replace Inheritedwidget.
The main selling point of
flutter-provide
seem to be able to use multiple providers at once; which is already supported byprovider
throughMultiProvider
What is the reasoning by creating a new one?
The text was updated successfully, but these errors were encountered: