- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 525
Description
Problem:
MultiProvider
is a very important feature for a provider. But it is currently tedious and error-prone to make a widget compatible with MultiProvider
:
- we have to implement
SingleChildCloneableWidget
, that is very error-prone (easy to forget a parameter) - it usually requires an extra private constructor, just for the clone implementation
All in all, it's too complex, which makes peoples not want to make custom providers and stick to the existing ones.
Solution
I made a POC of an alternate implementation of MultiProvider, which doesn't relly on a "clone" method.
Instead, it uses a new kind of widget (neither Stateless nor Stateful): SingleChildStatelessWidget / SingleChildStatefulWidget.
The difference is that the build
method takes an extra Widget child
parameter:
class Example extends SingleChildStatelessWidget {
Example({Key key, Widget child}): super(key: key, child: child);
@override
Widget build(BuildContext context, {Widget child}) {
// TODO: do something with `child`
}
}
Which is then instantly compatible with MultiProvider
:
MultiProvider(
providers: [
Example(),
],
)
Consequences:
The SingleChildCloneableWidget
interface will be removed, and replaced by a SingleChildWidget
interface and two implementations:
SingleChildStatelessWidget
SingleChildStatefulWidget
MultiProvider
will then accept a SingleChildWidget
instead of SingleChildCloneableWidget
Existing implementations of SingleChildCloneableWidget
should be migrated to use one of the two SingleChildWidget
implementation instead.
Before:
class Example extends StatelessWidget implements SingleChildCloneableWidget {
Example({Key key, int value, this.child}): this(key: key, foo: Foo(value), child: child);
Example._({Key key, this.foo, this.child): super(key: key);
final Foo foo;
final Widget child;
@override
Widget build(BuildContext context) {
return Whatever(
foo: foo,
child: child,
);
}
@override
Example cloneWithChild(Widget child) {
return Example._(
key: key,
foo: foo,
child: child,
);
}
}
After:
class Example extends SingleChildStatelessWidget {
Example({Key key, int value, Widget child}): foo = Foo(value), super(key: key, child: child);
final Foo foo;
@override
Widget build(BuildContext context, {Widget child}) {
return Whatever(
foo: foo,
child: child,
);
}
}
Activity
lookfirst commentedon Dec 24, 2019
I had to specially import this:
import 'package:provider/single_child_widget.dart';
awhitford commentedon Feb 19, 2020
Is there a reason why
single_child_widget
is not included when importingpackage:provider/provider.dart
?rrousselGit commentedon Feb 19, 2020
It pollutes the auto complete for things not directly related to provider.