I’m using Riverpod with StateProvider for my app.
The home page will change based on tabs clicked.
When i click the ListTile tab to trigger the ref.read, it rebuild super fast:
But when i click the leading IconButton in Appbar which trigger ref.read(countProvider.notifier).state = 0;
it takes me fews seconds to reload the back to 0. How do i fix this?
Full code:
layout.dart:
Set<Widget> _pages = {
const HomeUI(),
const FAQ(),
const Setting(),
};
class Layout extends ConsumerStatefulWidget {
const Layout({super.key});
@override
LayoutState createState() => LayoutState();
}
class LayoutState extends ConsumerState<Layout> {
bool isHome = true;
@override
Widget build(BuildContext context) {
final tab = ref.watch(countProvider);
if (tab != 0) {
isHome = false;
} else {
isHome = true;
}
return Scaffold(
drawer: const Sidebar(),
appBar: isHome
? AppBar(
leading: Builder(builder: (context) {
return IconButton(
icon: const Icon(FontAwesomeIcons.bars),
color: CustomColors.mainText,
onPressed: () {
Scaffold.of(context).openDrawer();
},
);
}),
actions: [
Padding(
padding: const EdgeInsets.only(right: 20),
child: IconButton(
icon: const Icon(FontAwesomeIcons.magnifyingGlass),
color: CustomColors.mainText,
onPressed: () {},
),
),
],
backgroundColor: Colors.transparent,
)
: null,
backgroundColor: CustomColors.background,
body: Stack(children: <Widget>[
_pages.elementAt(tab),
const MiniPlayer(),
]),
);
}
}
faq_screen.dart
class FAQ extends StatelessWidget {
const FAQ({super.key});
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, ref, child) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
ref.read(countProvider.notifier).state = 0;
},
),
title: const Text('FAQ'),
),
body: const Center(
child: Text('FAQ'),
),
);
},
);
}
}
sidebar.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../utilities/color.dart';
import '../utilities/provider.dart';
class Sidebar extends StatelessWidget {
const Sidebar({super.key});
@override
Widget build(BuildContext context) {
return Drawer(
backgroundColor: CustomColors.background,
child: Consumer(
builder: (context, ref, child) => ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: const Text("Wolhaiksong",
style: TextStyle(
color: Colors.white,
fontFamily: 'Gilroy',
fontWeight: CustomColors.semiBold)),
accountEmail: const Text("[email protected]",
style: TextStyle(
color: Colors.white,
fontFamily: 'Gilroy',
fontWeight: CustomColors.regular)),
currentAccountPicture: CircleAvatar(
child: ClipOval(
child: Image.asset('assets/user.jpg'),
),
),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/wallpaper.jpg'),
fit: BoxFit.cover),
),
),
ListTile(
leading: const Icon(
FontAwesomeIcons.lightbulb,
color: CustomColors.gray,
),
title: const Padding(
padding: EdgeInsets.all(15.0),
child: Text('FAQs',
style: TextStyle(
color: CustomColors.mainText,
fontWeight: CustomColors.semiBold,
fontFamily: 'Gilroy',
)),
),
onTap: () {
ref.read(countProvider.notifier).state = 1;
Navigator.pop(context);
},
),
ListTile(
leading: const Icon(
FontAwesomeIcons.gear,
color: CustomColors.gray,
),
title: const Padding(
padding: EdgeInsets.all(15.0),
child: Text('Settings',
style: TextStyle(
color: CustomColors.mainText,
fontWeight: CustomColors.semiBold,
fontFamily: 'Gilroy',
)),
),
onTap: () {
ref.read(countProvider.notifier).state = 2;
Navigator.pop(context);
},
),
],
),
),
);
}
}
provider.dart
final countProvider = StateProvider<int>((ref) {
return 0;
});
2
Answers
I'm sorry guys, turns out the problem is not Riverpod but the async function i used to extract dominant color from the image.
And I use it in initState so it runs everytime countProvider change
Is there anyway to move the async function outside of this or prevent initState from rerun everytime rebuilt?
Since you basically want to reset your provider to 0, instead of setting the value directly, you can try this: