Does setState rebuild the whole widget tree for a screen in flutter and how does it compare with other State management
If I say something wrong, someone please correct me.
Answering your questions in order:
If you call
setState()
onWidgetB
it'll rebuild itself and it's descendants, no matter if they areStateless
orStateful
Widgets.Using the BLoC approach, most of the times it's optional to use
Stateful Widgets
andsetState()
to manage State. In this approach you'll useevents
from the UI, which will be converted into 'States' inside your BLoC. This States will be passed into a Stream. Your UI will rebuild itself usingStreamBuilders
every time they listen to a new value on the Stream they're listening. This will trigger theStreamBuilder
to rebuilt itself and it's descendants.If you're using
BLoC
orProvider
+Streams
, I would recommend avoidingsetState()
andStatefulWidgets
, maybe with some exceptions like UI things, eg. animations.BLoC is a design approach with goes nice with the
Provider package
. TheBLoC package
even usesProvider
internally.
P.S.: Whereas BLoC
is an Architecture Pattern to manage the Data and State of your application. Provider is 'just' a wrapper around Inherited Widgets
that facilitate exposure of Data throughout your Widget tree, not an Architecture Pattern.
Other example of architecture pattern solution to manage state that uses the provider
package is MobX
.
setState() will call the build() method and rebuilds with widget tree (With Flutter optimizations under the hood), if you wish to build only a part there is an Alternative: create a Provider that holds the change that you want to reflect in the UI, and wrap that widget with a Consumer - when you will call notifyListener() from the Provider only that Widget will rebuild.
For Example:
child: Consumer<MessageIconStateProvider>( builder: (context, messageIconProvider, child) { return Container( height: 40, child: messageIconProvider.isShowMessageIcon ? Icon( Icons.send, size: 24, color: Colors.white, ) : Icon( Icons.mic_outlined, size: 24, color: Colors.white, ), ); } )
The provider:
import 'package:flutter/material.dart';class MessageIconStateProvider with ChangeNotifier { var isShowMessageIcon = true; void setIconToMessage(bool setIconToMessage){ if(setIconToMessage != isShowMessageIcon) { isShowMessageIcon = setIconToMessage; notifyListeners(); } }}
And don't forget to define it on your main.dart file:
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => MessageIconStateProvider()), ],...