Каково решение инициализации вещей внутри consumerWidget, поскольку метод initState здесь не может быть переопределен?
Riverpod: альтернативный способ переопределения initState внутри ConsumerWidget
Ответы (3)
Обновлено
Из Riverpod v1.0.0-dev.2
Вы можете использовать ConsumerStatefulWidget и ConsumerState
final helloWorldProvider = Provider((_) => 'Hello world');
class RiverpodExample extends ConsumerStatefulWidget {
@override
_RiverpodExampleState createState() => _RiverpodExampleState();
}
class _RiverpodExampleState extends ConsumerState<Example> {
@override
void initState() {
super.initState();
final value = ref.read(helloWorldProvider);
}
@override
Widget build(BuildContext context) {
final value = ref.watch(helloWorldProvider);
return Text(value); // Hello world
}
}
или добавьте ConsumerStateMixin
миксин в свой класс StatefulWidget
class StatefulExample extends StatefulWidget {
@override
_StatefulExampleState createState() => _StatefulExampleState();
}
class _StatefulExampleState extends State<StatefulExample> with ConsumerStateMixin {
void initState() {
super.initState();
// You can access WidgetReference (ref)
final value = ref.read(helloWorldProvider);
}
@override
Widget build(BuildContext context) {
A value = ref.watch(a);
return Container();
}
}
Взгляните на эту проблему - https://github.com/rrousselGit/river_pod/issues/335
До Riverpod v0.14.0 + 3
Вы должны использовать StatefulWidget
и вернуть Consumer в качестве корневого виджета. из метода build
.
Потребитель
Consumer можно использовать для прослушивания поставщиков внутри StatefulWidget или для восстановления как можно меньшего количества виджетов при обновлении поставщика.
final helloWorldProvider = Provider((_) => 'Hello world');
class RiverpodExample extends StatefulWidget {
@override
_RiverpodExampleState createState() => _RiverpodExampleState();
}
class _RiverpodExampleState extends State<Example> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, watch, child) {
final value = watch(helloWorldProvider);
return Text(value); // Hello world
},
);
}
}
Я не совсем уверен, как ответить на ваш вопрос, поскольку я не работал с ConsumerWidget. Я предполагаю, что идея состоит в том, чтобы сохранить большую часть вашего состояния в провайдерах.
Однако я хотел бы порекомендовать использовать hooks_riverpod вместе с flutter_hooks (тот же разработчик).
Это упрощает сохранение локального состояния виджета, а также обеспечивает легкий доступ к поставщикам.
Например:
class Example extends HookWidget {
const Example({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final test = useProvider(Test.provider());
final controller = useTextEditingController();
final loading = useState(false);
final buttonText = useState('Change me!');
return Column(
children: [
TextField(controller: controller),
if (!loading) RaisedButton(
onPressed: () async {
loading.value = true;
await Future.delayed(const Duration(seconds: 1));
buttonText.value = controller.text;
loading.value = false;
}
child: Text(buttonText.value),
),
if (loading) const CircularProgressIndicator(),
// Do something with providers, etc.
],
),
);
}
Просто быстрый пример, но ресурсов много (flutter_hooks, hooks_riverpod), чтобы помочь вам. Также ознакомьтесь с примерами от разработчика использования крючков Riverpod.
Возможно, я опоздаю, но с выходом Riverpod 1.0.0 вы сможете использовать https://pub.dev/documentation/flutter_riverpod/1.0.0-dev.2/flutter_riverpod/ConsumerStatefulWidget-class.html и https://pub.dev/documentation/flutter_riverpod/1.0.0-dev.2/flutter_riverpod/ConsumerState-class.html, который делает именно то, что вы хотите.