Open brianegan opened 3 years ago
I'll add that this is a template, so it's understood that the approach isn't going to be the complete, final one. Many frameworks provide templates that don't even work at all (e.g. the detail view is always the same).
In templates, it is completely okay if the developer needs to replace the approach (or lack thereof) with something else right off the bat. Ideally, the process of replacing wouldn't be too painful, though.
I think it makes more sense to use constructors, to keep it simple and easier to understand for people new to flutter.
You probably also don't want to "pick a winning team" by showcasing a particular library. Perhaps mention in the comments that there are a lot of ways to achieve the same goal and list the top 10 (or whatever) alternatives.
Template based on another figurative template. Constructors should be the better option out there. Once you utilize other dependence like the one highlighted by you, it means a new developer has to learn that before they can use the template. Anything can happen in the future. What if everything change for the dependence, we have assumptions everywhere.
Suggestion 🍟
I think that we should avoid community solutions here, and should use plain Dart constructors for an example. This will allow to don't add an extra layer of complexity for newcomers.
Constructor works great for very shallow trees or when being near to a leaf. I wouldn't use it to propagate global app state, though. Choosing a specific package, on the other hand, is hard too. That being said, I feel like people starting don't wanna have to choose 'The mechanism by which data is passed along the element tree', so having provider (which is the most well-known solution) be the default sounds good to me. Probably best to add documentation on what exactly provider is solving in that instance and how other packages could solve that too (with links)
Thanks so much for the feedback so far, everyone :) Very good points all around!
I totally feel like that a template should have an agnostic approach on dependencies. Since this is targeting beginner-intermediate folks I feel like it would be counter productive to introduce an opinionated tool that hide all the complexity. Also true is that this tools are coming in with trade-offs which cost may vary from project to project, it will be a bit annoying to have to remove things from a template that is suppose to show me the simplest yet comprehensive way of starting up a project.
If people take this template as a guidance, I think that we shouldn't pass data through constructors. It makes things harder to maintain and has a lot of drawbacks. I think that we should show how to pass data through the widget tree thanks to InheritedWidgets
without the help of an external package.
We could create a vanilla Flutter widget like this one:
class ValueProvider<T> extends StatelessWidget {
const ValueProvider({
Key key,
@required this.value,
@required this.child,
}) : assert(child != null),
super(key: key);
final T value;
final Widget child;
@override
Widget build(BuildContext context) {
return _InheritedValue<T>(
value: value,
child: child,
);
}
static T of<T>(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<_InheritedValue<T>>()
.value;
}
}
class _InheritedValue<T> extends InheritedWidget {
_InheritedValue({
Key key,
@required this.value,
@required Widget child,
}) : super(key: key, child: child);
final T value;
@override
bool updateShouldNotify(_InheritedValue<T> oldWidget) {
return oldWidget.value != value;
}
}
This is a simple solution which mimics the common use case of the Provider
package and shows how to use InheritedWidgets
.
To retrieve data in the build method of a widget we would call this ValueProvider.of<T>(context)
.
There are many ways to pass values from parent to descendant Widgets. Passing via constructors can be educational for newer Flutter developers, but most projects appear to include some kind of library like Provider, Riverpod or get_it to make such passing easier.
Should the template provide concrete guidance on how to pass dependencies down the Widget tree, or should the template pass dependencies via normal Class constructors?