Fabian M
Fabian M

Reputation: 278

Flutter bad practice to execute functions inside Widget build?

I want to listen to the current theme permanently because I had some issues with the systemchrom, so I found a workaround for that where I call a BlocProvider.of inside my Widget build. In general, it works perfectly fine now, but is this a clean solution or not a good practice, if last, is there a better way of listening to a SystemUiOverlayStyle permanently?

@override
  Widget build(BuildContext context) {
BlocProvider.of<SysUiCubit>(context).changeTheme(context, isDarkMode);
 return BlocBuilder<SysUiCubit, SysUiState>(
      builder: (context, state) {
        return AnnotatedRegion<SystemUiOverlayStyle>(

I added a small logic inside the build so the BlocProvider only gets called when the theme changes:

bool buildOnce =false;
  @override
  Widget build(BuildContext context) {

    bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
    if(!buildOnce){
      setPrev(Theme.of(context).brightness == Brightness.dark);
    buildOnce=true;
    }
    if(darkmodePrev != isDarkMode){
      BlocProvider.of<SysUiCubit>(context).changeTheme(context, isDarkMode);
      buildOnce=false;
    }

Same thing I asked myself on another point at my app:

  @override
  Widget build(BuildContext context) {
    final todo= context.watch<TodoListCubit>().state.todo;

    return BlocListener<TodoListCubit, TodoListState>(
        listener: (context, state) {

Here I have a todo list where I call context.watch inside my build function - same question - I didn't find a cleaner solution for updating the todo list every time the widget rebuilds, so is this okay or a bad practice?

Upvotes: 0

Views: 898

Answers (1)

krishnaacharyaa
krishnaacharyaa

Reputation: 25040

Bad Practice

Defining a function inside the build

Good Practice (To be followed)

Define a function outside the build and call it inside the function which will help you rebuild the widget if needed.


For your problem, I suggest you emit changes when the theme changes and rebuild the widget using buildWhen instead of embedding this work around inside the build.

That would be considered more cleaner code, If this is what you are looking for.


Use something like, example from the official docs:

class ThemeCubit extends Cubit<ThemeData> {
  /// {@macro brightness_cubit}
  ThemeCubit() : super(_lightTheme);

  static final _lightTheme = ThemeData(
    floatingActionButtonTheme: const FloatingActionButtonThemeData(
      foregroundColor: Colors.white,
    ),
    brightness: Brightness.light,
  );

  static final _darkTheme = ThemeData(
    floatingActionButtonTheme: const FloatingActionButtonThemeData(
      foregroundColor: Colors.black,
    ),
    brightness: Brightness.dark,
  );

  /// Toggles the current brightness between light and dark.
  void toggleTheme() {
    emit(state.brightness == Brightness.dark ? _lightTheme : _darkTheme);
  }
}

BlocBuilder<BlocA, BlocAState>(
  buildWhen: (previousState, state) {
    // return true/false to determine whether or not // 👈 add your logic here
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)

Upvotes: 2

Related Questions